Fix excessive CPU usage when the number of sockets exceeds the system limit.
Closes #948. Thanks to wiebeytec.
This commit is contained in:
parent
ba175e581e
commit
ee8e20de75
@ -4,9 +4,11 @@
|
|||||||
Broker:
|
Broker:
|
||||||
- Fix build when using WITH_ADNS=yes.
|
- Fix build when using WITH_ADNS=yes.
|
||||||
- Fix incorrect call to setsockopt() for TCP_NODELAY. Closes #941.
|
- Fix incorrect call to setsockopt() for TCP_NODELAY. Closes #941.
|
||||||
|
- Fix excessive CPU usage when the number of sockets exceeds the system limit.
|
||||||
|
Closes #948.
|
||||||
|
|
||||||
Build:
|
Build:
|
||||||
- Make it easier to build with bundled uthash.h using "WITH_BUNDLED_DEPS=no".
|
- Make it easier to build without bundled uthash.h using "WITH_BUNDLED_DEPS=no".
|
||||||
|
|
||||||
|
|
||||||
1.5.1 - 20180816
|
1.5.1 - 20180816
|
||||||
|
@ -239,6 +239,7 @@ int main(int argc, char *argv[])
|
|||||||
memset(&int_db, 0, sizeof(struct mosquitto_db));
|
memset(&int_db, 0, sizeof(struct mosquitto_db));
|
||||||
|
|
||||||
net__init();
|
net__init();
|
||||||
|
int_db.spare_sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
|
||||||
config__init(&int_db, &config);
|
config__init(&int_db, &config);
|
||||||
rc = config__parse_args(&int_db, &config, argc, argv);
|
rc = config__parse_args(&int_db, &config, argc, argv);
|
||||||
|
@ -392,6 +392,7 @@ struct mosquitto_db{
|
|||||||
#ifdef WITH_EPOLL
|
#ifdef WITH_EPOLL
|
||||||
int epollfd;
|
int epollfd;
|
||||||
#endif
|
#endif
|
||||||
|
mosq_sock_t spare_sock;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum mosquitto__bridge_direction{
|
enum mosquitto__bridge_direction{
|
||||||
|
26
src/net.c
26
src/net.c
@ -97,7 +97,31 @@ int net__socket_accept(struct mosquitto_db *db, mosq_sock_t listensock)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
new_sock = accept(listensock, NULL, 0);
|
new_sock = accept(listensock, NULL, 0);
|
||||||
if(new_sock == INVALID_SOCKET) return -1;
|
if(new_sock == INVALID_SOCKET){
|
||||||
|
#ifdef WIN32
|
||||||
|
errno = WSAGetLastError();
|
||||||
|
if(errno == WSAEMFILE){
|
||||||
|
#else
|
||||||
|
if(errno == EMFILE || errno == ENFILE){
|
||||||
|
#endif
|
||||||
|
/* Close the spare socket, which means we should be able to accept
|
||||||
|
* this connection. Accept it, then close it immediately and create
|
||||||
|
* a new spare_sock. This prevents the situation of ever properly
|
||||||
|
* running out of sockets.
|
||||||
|
* It would be nice to send a "server not available" connack here,
|
||||||
|
* but there are lots of reasons why this would be tricky (TLS
|
||||||
|
* being the big one). */
|
||||||
|
COMPAT_CLOSE(db->spare_sock);
|
||||||
|
new_sock = accept(listensock, NULL, 0);
|
||||||
|
if(new_sock != INVALID_SOCKET){
|
||||||
|
COMPAT_CLOSE(new_sock);
|
||||||
|
}
|
||||||
|
db->spare_sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
log__printf(NULL, MOSQ_LOG_NOTICE,
|
||||||
|
"Unable to accept new connection, system socket count has been exceeded. Try increasing \"ulimit -n\" or equivalent.");
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
G_SOCKET_CONNECTIONS_INC();
|
G_SOCKET_CONNECTIONS_INC();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user