Antonio, from my experience calling apr_socket_close() on a socket where another thread is currently apr_socket_recv()'ing is not thread-safe. It is accidentally "safe" on most platforms but at least on Darwin this can lead to segfaults (caused by Darwin's curious implementation of the pollset API). I have a kind of hackish patch for APR if anyone needs it but I guess this should be addressed by someone who understands the API better than I do.
-- Ignaz 2011/9/2 Antonio Vieiro <[email protected]>: > D'oh! > > It seems apr_socket_accept requires a brand new apr_pool_t as third > argument, reusing an existing one is problematic. I didn't know that. > Maybe it's worth a comment in the documentation. > > Cheers, > Antonio > > 2011/9/1 Antonio Vieiro <[email protected]>: >> Hi all, >> >> I'm a little confused regarding apr_socket_close thread-safety and >> maybe someone can help me here. >> >> I'm building a small socket server. On the main thread (thread 1 >> below) I spawn different threads that run a function named >> 'request_processor_function' (below). >> >> The main thread then accepts requests and inserts them in a >> thread-safe queue, and the 'request_processor_function' listens for >> requests in this queue and processes them. >> >> The fact is that I want each thread to close the connection when the >> request is processed, so at the end of my thread function I invoke a >> apr_socket_close. >> >> Thinks work without problems, but then suddently everything stops >> running and I see threads locked in apr_pool_cleanup_exit, which is >> invoked from apr_socket_close (see below for an excerpt of a gdb >> session). >> >> My question is: how do I thread-safely invoke apr_socket_close? Shall >> I create a mutex on the main thread and then sequentially invoke >> apr_socket_close? >> >> Thanks in advance, >> Antonio >> >> P.S.: gdb excerpt with the problem: >> >> (gdb) info threads >> 11 Thread 0xb2cfcb70 (LWP 15719) 0xb7efcddb in >> apr_pool_cleanup_kill () from /usr/lib/libapr-1.so.0 >> 10 Thread 0xb34fdb70 (LWP 15718) 0xb7efcddb in >> apr_pool_cleanup_kill () from /usr/lib/libapr-1.so.0 >> 9 Thread 0xb3cfeb70 (LWP 15717) 0xb7efcddb in apr_pool_cleanup_kill >> () from /usr/lib/libapr-1.so.0 >> 8 Thread 0xb44ffb70 (LWP 15716) 0xb7efcd93 in apr_pool_cleanup_kill >> () from /usr/lib/libapr-1.so.0 >> 7 Thread 0xb4e8cb70 (LWP 15715) 0xb7efcddb in apr_pool_cleanup_kill >> () from /usr/lib/libapr-1.so.0 >> 6 Thread 0xb568db70 (LWP 15714) 0xb7efcdc9 in apr_pool_cleanup_kill >> () from /usr/lib/libapr-1.so.0 >> 5 Thread 0xb5e8eb70 (LWP 15713) 0xb7efcd99 in apr_pool_cleanup_kill >> () from /usr/lib/libapr-1.so.0 >> 4 Thread 0xb668fb70 (LWP 15712) 0xb7efcdd4 in apr_pool_cleanup_kill >> () from /usr/lib/libapr-1.so.0 >> 3 Thread 0xb6e90b70 (LWP 15711) 0xb7efcd99 in apr_pool_cleanup_kill >> () from /usr/lib/libapr-1.so.0 >> 2 Thread 0xb7891b70 (LWP 15710) 0xb7efcddb in apr_pool_cleanup_kill >> () from /usr/lib/libapr-1.so.0 >> * 1 Thread 0xb78c8720 (LWP 15695) 0xb7fe1424 in __kernel_vsyscall () >> (gdb) thread 11 >> [Switching to thread 11 (Thread 0xb2cfcb70 (LWP 15719))]#0 0xb7efcddb >> in apr_pool_cleanup_kill () from /usr/lib/libapr-1.so.0 >> (gdb) backtrace >> #0 0xb7efcddb in apr_pool_cleanup_kill () from /usr/lib/libapr-1.so.0 >> #1 0xb7efceb6 in apr_pool_cleanup_run () from /usr/lib/libapr-1.so.0 >> #2 0xb7effa9b in apr_socket_close () from /usr/lib/libapr-1.so.0 >> #3 0x080515d1 in thread_close_socket (client_socket=0xb454e7d0) at >> server.c:449 >> #4 0x08051815 in request_processor_function (thread=0x879b070, >> data=0x86f8880) at server.c:491 >> #5 0xb7f0a681 in ?? () from /usr/lib/libapr-1.so.0 >> #6 0xb7a9ce99 in start_thread (arg=0xb2cfcb70) at pthread_create.c:304 >> #7 0xb7e5373e in clone () at ../sysdeps/unix/sysv/linux/i386/clone.S:130 >> (gdb) >> >
