Hi Damon,

You're right, the combination of MHD_NO_LISTEN_SOCKET and MHD internal
threads did not work properly. However, the 'race' you are trying to fix
doesn't really apply. Also,
I think it is a bit safer to test for the existence of the IPC socket
before creating the threads in the no-listen-socket case (as otherwise
we cannot stop the threads). But, that should be a very, very minor detail.

After confirming that it seems to fix the test you provided, I have now
pushed a patch to Git  as revision efd1dd05..1d9f940d. The fix is a
minor variation on your suggestion, so thanks for the report and diagnosis!

Happy hacking!

Christian

On 9/23/20 11:28 PM, Damon Earp wrote:
> 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)
>      {

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to