[Libevent-users] SIGPIPE in multithreaded program

Ron Arts ron.arts at neonova.nl
Tue Jan 22 02:51:55 EST 2008


William Ahern wrote:
> On Tue, Jan 22, 2008 at 01:06:30AM +0100, Ron Arts wrote:
>> Hi,
>>
>> I am using libevent in a multithreaded program, the main
>> thread containing the libevent loop, and other threads
>> doing disk I/O. From mail from this list, and the changelogs
>> I was under the impression that libevent handles signals
>> better in a multithreaded environment since 1.3, but now
>> I think I was wrong.
>>
>> Is it necessary to specifically ignore signals in every
>> thread I create?
> 
> In Unix it's necessary to change the default behavior of SIGPIPE if you
> don't want your process killed. libevent, AFAIK, won't do this for you. If
> won't independently setup handlers for all the different signals. Most
> daemon applications ignore SIGPIPE as part of their initialization. The
> default behavior caters to simple shell applications that can't be bothered
> to check the return value of a write.
> 
> 	#include <signal.h>
> 
> 	struct sigaction sa;
> 
> 	sa		= sa_initializer;
> 	sa.sa_handler	= SIG_IGN;
> 	sa.sa_flags	= 0;
> 
> 	sigemptyset(&sa.sa_mask);
> 
> 	if (0 != sigaction(SIGPIPE, &sa, 0))
> 		err(EXIT_FAILURE, "sigaction");

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:

   struct event evsigpipe;

   event_init();
   event_set(&evsigpipe, SIGPIPE, EV_SIGNAL|EV_PERSIST, signal_cb, &evsigpipe);
   event_add(&evsigpipe, NULL);
   event_dispatch();

void signal_cb(int fd, short event, void *arg)
{
   struct event *signal = arg;
extern int reload_database;

   switch(EVENT_SIGNAL(signal)) {
     case SIGTERM: // sigterm
         fprintf(stderr, "Killed");
         exit(1); break;
     case SIGHUP:  // sighup
         fprintf(stderr, "Got SIGHUP");
         reload_config = TRUE;
         break;
     case SIGUSR1:  // reload entire database
         fprintf(stderr, "Got SIGUSR1");
         reload_database = TRUE;
         break;
     default:
         fprintf(stderr, "%s: got signal %d", __func__, EVENT_SIGNAL(signal));
         break;
   }
}

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?
Or should I specifically add code at the beginning of each thread
to ignore SIGPIPE?

Thanks,
Ron

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

-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 3295 bytes
Desc: S/MIME Cryptographic Signature
Url : http://monkeymail.org/archives/libevent-users/attachments/20080122/ae41efba/smime-0001.bin


More information about the Libevent-users mailing list