Re: Re: [Libevent-users] thread-safety (and performance)

2008-01-22 Thread Tani Hosokawa



On Mon, Jan 21, 2008 at 04:14:08PM -0800, Tani Hosokawa wrote:


> @@ -1999,7 +1999,7 @@
>if ((fd = bind_socket(address, port)) == -1)
>return (-1);
> 
> -   if (listen(fd, 10) == -1) {

> +   if (listen(fd, 8192) == -1) {
>event_warn("%s: listen", __func__);
>EVUTIL_CLOSESOCKET(fd);
>return (-1);

Probably better to use SOMAXCONN instead of an arbitrary number.

On Linux, you can set somaxconn in proc (|/proc/sys/net/core/somaxconn) to much 
higher than the value in the header files (128).  I could pull the sysctl 
value, but that isn't all that portable and in any case it's silently truncated 
to the system's real maximum if you specify something higher.  As libevent is 
typically used for high performance products, it makes sense to me to set it 
above the system's actual maximum, and let the system limits drag it down.  If 
anyone has some portable code for determining the real somaxconn across all 
systems, that'd probably be handy.



|

___
Libevent-users mailing list
Libevent-users@monkey.org
http://monkeymail.org/mailman/listinfo/libevent-users


Re: [Libevent-users] SIGPIPE in multithreaded program

2008-01-22 Thread William Ahern
On Tue, Jan 22, 2008 at 02:08:40PM +0100, Hannah Schroeter wrote:

> >With SIGPIPE the answer is simple, though. Block the signal from the main
> >thread before creating any other threads. All threads will inherit the
> >block, and SIGPIPE can never squeeze through.
> 
> I think you mean *ignore* SIGPIPE.
> 

Right. It's late. (Or was late; now it's morning again.)

At this point I've lost enough points that I ought to take a refresher
course myself ;) 

___
Libevent-users mailing list
Libevent-users@monkey.org
http://monkeymail.org/mailman/listinfo/libevent-users


Re: [Libevent-users] SIGPIPE in multithreaded program

2008-01-22 Thread Hannah Schroeter
Hi!

On Tue, Jan 22, 2008 at 12:52:51AM -0800, William Ahern wrote:

>Signal handlers and masks are inherited across fork() and pthread_create().
>And masks are inherited across exec(), too, I think.

>You could add code to each thread to do this. Of course, there are race
>conditions. Imagine if a signal is raised after a thread starts but before
>it can block the signal. This is especially troublesome if you dynamically
>create threads.

A way to avoid the race is to block all signals (using pthread_sigmask)
in main() early and unblock them in *one* thread (which is in duty for
signal handling) *only* later, after having created the other threads.
If you create threads afterwards, block them again before pthread_create
and unblock again afterwards, again. Then the other threads all inherit
the signal mask blocking all signals so there's always only at maximum
one thread which gets the signals.

>With SIGPIPE the answer is simple, though. Block the signal from the main
>thread before creating any other threads. All threads will inherit the
>block, and SIGPIPE can never squeeze through.

I think you mean *ignore* SIGPIPE.

>But, by block I mean actually using sigaction(2) (see the code I posted
>earlier), not by installing a libevent handler. Installing a SIGPIPE handler
>through libevent is pointless and a waste of CPU, and of course it doesn't
>do what you want anyway.

sigaction doesn't *block* signals in Unix/POSIX terminology. It sets up
signal *handling*, to either default handling, user handling or ignoring
the signal.

With libevent, you either ignore a signal using sigaction or you handle
it using libevent and don't touch it yourself with sigaction (but you
may block/unblock it using sigprocmask [in single threaded programs] or
pthread_sigmask [in multithreaded programs]).

Your recommendation of *ignoring* SIGPIPE still stands, and instead you
handle EPIPE in write(2) (or send(2)).

>[...]

Kind regards,

Hannah.
___
Libevent-users mailing list
Libevent-users@monkey.org
http://monkeymail.org/mailman/listinfo/libevent-users


Re: [Libevent-users] SIGPIPE in multithreaded program

2008-01-22 Thread Ron Arts
William Ahern schreef:

> 
> Signal handlers and masks are inherited across fork() and pthread_create().
> And masks are inherited across exec(), too, I think.
> 

Yes, of course, I should've thought of that myself.

> You could add code to each thread to do this. Of course, there are race
> conditions. Imagine if a signal is raised after a thread starts but before
> it can block the signal. This is especially troublesome if you dynamically
> create threads.
> 
> With SIGPIPE the answer is simple, though. Block the signal from the main
> thread before creating any other threads. All threads will inherit the
> block, and SIGPIPE can never squeeze through.
> 
> But, by block I mean actually using sigaction(2) (see the code I posted
> earlier), not by installing a libevent handler. Installing a SIGPIPE handler
> through libevent is pointless and a waste of CPU, and of course it doesn't
> do what you want anyway.
> 

Why is it pointless? I indeed noticed it doesn't catch signals (I think
my other signals do not get through as well), but libevent comes with
an example program.

> Signals are probably the most complex and difficult to understand concept in
> Unix, and understanding how to safely use them is even more difficult. I
> suggest you find a copy of Richard Stevens' Advanced Programming in the UNIX
> Environment.
> 
> If Knuth and Stevens have (had) one thing in common, it's that no engineer
> would ever question why you one of their books sat on your book shelf.

I know, and I used to own them both, but the former was hijacked by my
oldest son, and the latter just magically disappeared from my bookshelf...

Thanks,
Ron

> ___
> Libevent-users mailing list
> Libevent-users@monkey.org
> http://monkeymail.org/mailman/listinfo/libevent-users


-- 
NeoNova BV, The Netherlands
Professional internet and VoIP solutions

http://www.neonova.nl   Kruislaan 419  1098 VA Amsterdam
info: 020-5628292   servicedesk: 020-5628292   fax: 020-5628291
KvK Amsterdam 34151241

The following disclaimer applies to this email:
http://www.neonova.nl/maildisclaimer


smime.p7s
Description: S/MIME Cryptographic Signature
___
Libevent-users mailing list
Libevent-users@monkey.org
http://monkeymail.org/mailman/listinfo/libevent-users


Re: [Libevent-users] SIGPIPE in multithreaded program

2008-01-22 Thread William Ahern
On Tue, Jan 22, 2008 at 08:51:55AM +0100, Ron Arts wrote:

> Oops, I'm sorry, I did not make myself clear, while writing the
> email I edited it a lot, and forgot to mention that indeed I
> ignore SIGPIPE in my initialisation code:
> 

> 
> But my program is still being killed with SIGPIPE occasionally.
> I am using threads, and I presume sometimes one of the other threads
> receives the SIGPIPE signal instead of the main thread, and I
> *think* that in such a case my program exits.
> 
> But what I meant to ask was: isn't libevent supposed (since 1.3) to handle
> multithreading and ensure that only one thread receives the signal?

Neither libevent nor anything else can specify that any particular thread
receive a signal. All that can be done is to block a signal in all threads
except for one, which gives the same effect in a round-about manner.

Since libevent doesn't create the threads, it can't block them like this.
And, in any event, it would be evil for libevent to fiddle with signals this
way behind a process' back. I wouldn't want libevent to preemptively block
all signals from event_init().

> Or should I specifically add code at the beginning of each thread
> to ignore SIGPIPE?

Signal handlers and masks are inherited across fork() and pthread_create().
And masks are inherited across exec(), too, I think.

You could add code to each thread to do this. Of course, there are race
conditions. Imagine if a signal is raised after a thread starts but before
it can block the signal. This is especially troublesome if you dynamically
create threads.

With SIGPIPE the answer is simple, though. Block the signal from the main
thread before creating any other threads. All threads will inherit the
block, and SIGPIPE can never squeeze through.

But, by block I mean actually using sigaction(2) (see the code I posted
earlier), not by installing a libevent handler. Installing a SIGPIPE handler
through libevent is pointless and a waste of CPU, and of course it doesn't
do what you want anyway.

Signals are probably the most complex and difficult to understand concept in
Unix, and understanding how to safely use them is even more difficult. I
suggest you find a copy of Richard Stevens' Advanced Programming in the UNIX
Environment.

If Knuth and Stevens have (had) one thing in common, it's that no engineer
would ever question why you one of their books sat on your book shelf.
___
Libevent-users mailing list
Libevent-users@monkey.org
http://monkeymail.org/mailman/listinfo/libevent-users