You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@apr.apache.org by Antonio Vieiro <an...@antonioshome.net> on 2011/09/01 19:14:33 UTC

apr_socket_close thread safe?

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)

Re: apr_socket_close thread safe?

Posted by Antonio Vieiro <an...@antonioshome.net>.
Hi,

Thanks for the tip, but the fact is that I'm apr_socket_close *after* 
any apr_socket_recv, so the patch won't apply.

As far as I understand apr_socket_close cleans up the apr_pool_t, so any 
new incoming socket should be created in a brand new apr_pool_t (or 
subpool).

Cheers,
Antonio

El 12/09/11 09:50, Ignaz Birnstingl escribió:
> 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.
>


Re: apr_socket_close thread safe?

Posted by Ignaz Birnstingl <ig...@gmail.com>.
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 <an...@antonioshome.net>:
> 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 <an...@antonioshome.net>:
>> 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)
>>
>

Re: apr_socket_close thread safe?

Posted by Antonio Vieiro <an...@antonioshome.net>.
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 <an...@antonioshome.net>:
> 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)
>