libmicrohttpd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [libmicrohttpd] Hang with MHD_OPTION_THREAD_POOL_SIZE on Windows


From: Christian Grothoff
Subject: Re: [libmicrohttpd] Hang with MHD_OPTION_THREAD_POOL_SIZE on Windows
Date: Sat, 8 Dec 2018 22:59:37 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.3.1

Hi Jonathan,

Hmm. This reads like the 'listen' socket is not properly set to
non-blocking on Windows (or W32 doesn't support non-blocking listen
sockets, which would be worse...).

Could you please check the syscalls MHD makes to setup the listen
socket? It needs to be non-blocking. I don't do W32 development, but
patches would be welcome!

Happy hacking!

Christian

On 12/8/18 1:07 AM, Jonathan McDougall wrote:
> I've been having problems with MHD_OPTION_THREAD_POOL_SIZE on Windows.
> I started with 0.9.55 from vcpkg, but then changed the portfile to use
> 0.9.61 instead. Both give the same results.
> 
> Connections to the server hang intermittently. More threads in the pool
> seems to make it hang more often. I think I was able to trace it back to
> a blocking call to accept() in MHD_accept_connection().
> 
> What I'm seeing is that all threads block on a select() call in
> MHD_select(). When a connection comes in, *multiple threads* wake up
> at the same time and end up in MHD_accept_connection(). Some of them
> seem to then block on accept().
> 
> Repeated calls of curl eventually works, but it can take a dozen calls
> before one goes through with 8 threads in the pool. Threads that are
> blocked in accept() seem to be able to eventually wake up and accept a
> connection.
> 
> I'm attaching a short repro below. Executing something like
> 'curl http://127.0.0.1:8080/a' usually hangs. There's nothing special in
> the code, I ripped it out of test_get.c. In fact, test_get.c itself
> hangs in testMultithreadedPoolGet().
> 
> I'm using Visual Studio 2019 Preview (16.0 P1) on Windows 10. I'm
> reproducing this on both x86 and x64.
> 
> 
> #include <microhttpd.h>
> #include <stdio.h>
> 
> int echo(
>       void* cls, struct MHD_Connection* connection, const char* url,
>       const char* method, const char* version,
>       const char* upload_data, size_t* upload_data_size,
>       void** unused)
> {
>       static int ptr;
>       struct MHD_Response* response;
>       int ret;
> 
>       if (&ptr != *unused)
>       {
>               *unused = &ptr;
>               return MHD_YES;
>       }
> 
>       *unused = NULL;
>       response = MHD_create_response_from_buffer(
>               strlen(url), (void*)url, MHD_RESPMEM_MUST_COPY);
> 
>       ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
>       MHD_destroy_response(response);
> 
>       return ret;
> }
> 
> int main()
> {
>       const unsigned int count = 8;
> 
>       struct MHD_Daemon* d = MHD_start_daemon(
>               MHD_USE_INTERNAL_POLLING_THREAD,
>               8080, NULL, NULL, &echo, NULL,
>               MHD_OPTION_THREAD_POOL_SIZE, count,
>               MHD_OPTION_END);
> 
>       getc(stdin);
> 
>       MHD_stop_daemon(d);
> 
>       return 0;
> }
> 

Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]