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