Yesterday, I sent an email about a file descriptor leak when using the epoll interface on Linux. Hence, today I attempted to use the less efficient select method instead.
However, I noticed that upon 1020 simultaneous client connections, the microhttp library runs into an busy loop (negating the benefits of waiting on select). A system call trace looks something along the lines of
socket(...) = 4
bind(4, ...)
select(5, ...)
accept4(4, ...) = 5
select(6, ...)
accept4(4, ...) = 6
...
select(1024, ...)
accept(4, ...) = -1 EMFILE (too many open files)
write(2, "error accepting connection: Too many open files ...)
select(1024, ...)
accept(4, ...) = -1 EMFILE (too many open files)
write(2, "error accepting connection: Too many open files ...)
select(1024, ...)
accept(4, ...) = -1 EMFILE (too many open files)
write(2, "error accepting connection: Too many open files ...)
...
Hence, when the accept4 call returns an error, microhttp goes into a busy loop, attempting to retry the accept4 call. However, it would make more sense that if the error is too many files open, that microhttp would stop accepting connections until one of the current connections is closed.
Since the maximum number of connections is hardcoded to 1024 on Linux, and by default the hard limit on the number of open files for any particular user is 4096, a workaround I have found is to increase the soft limit on the number of open files past 1024, which allows accept4 to not fail, and microhttp to immediately close the socket.
Sincerely,
Chris P