libmicrohttpd
[Top][All Lists]
Advanced

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

[libmicrohttpd] Hang with MHD_OPTION_THREAD_POOL_SIZE on Windows


From: Jonathan McDougall
Subject: [libmicrohttpd] Hang with MHD_OPTION_THREAD_POOL_SIZE on Windows
Date: Fri, 7 Dec 2018 19:07:51 -0500

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;
}

-- 
Jonathan McDougall



reply via email to

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