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

Reply via email to