[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;
> }
>
signature.asc
Description: OpenPGP digital signature