Hoping this is as a reply to my previous email.
I did some digging and below is a patch to daemon.c which allows an epoll internal thread to have connections added to it from another thread. This patch removes the condition where if MHD_NO_LISTEN_SOCKET is present the internal thread isn't started. And it moves setting the connection->epoll_state to before calling epoll_ctl avoiding a race condition when MHD_add_connection is called from another thread.
This patch is specific to epoll_internal w/o turbo and was done ad hoc by an ignorant developer. If another type of setup was used this patch would probably cause problems.
Are there other hazards to this? From my gdb tracing it looks like all the daemon accesses are synchronized, but I'm interested in getting some feedback from someone who actually knows the code and can point me in a better direction.
Thanks,
Damon
--- libmicrohttpd-0.9.71/src/microhttpd/daemon.c 2020-06-16 18:38:13.000000000 +0000
+++ libmicrohttpd-0.9.71-patched/src/microhttpd/daemon.c 2020-09-23 21:08:52.000000000 +0000
@@ -2718,11 +2718,13 @@
event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
event.data.ptr = connection;
+ connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET;
if (0 != epoll_ctl (daemon->epoll_fd,
EPOLL_CTL_ADD,
client_socket,
&event))
{
+ connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET;
eno = errno;
#ifdef HAVE_MESSAGES
MHD_DLOG (daemon,
@@ -6438,8 +6440,7 @@
}
#endif /* HTTPS_SUPPORT */
#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
- if ( (0 != (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) &&
- (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) )
+ if ( (0 != (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) )
{
if (0 == daemon->worker_pool_size)
{