Fix excessive CPU usage when the number of sockets exceeds the system limit.

Closes #948. Thanks to wiebeytec.
This commit is contained in:
Roger A. Light 2018-09-18 11:54:58 +01:00
parent ba175e581e
commit ee8e20de75
4 changed files with 30 additions and 2 deletions

View File

@ -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

View File

@ -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);

View File

@ -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{

View File

@ -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();