diff --git a/oop.h b/oop.h index d5d82ac534474e976d535c3a5403a619acd76536..7980f36ff9f4046c9c4259b640ed2fb18529f6f6 100644 --- a/oop.h +++ b/oop.h @@ -110,7 +110,10 @@ void oop_select_delete(oop_adapter_select *); /* Helper for event sources without signal handling. */ typedef struct oop_adapter_signal oop_adapter_signal; +#define OOP_SIGNAL_USE_RESTART 0x1 + oop_adapter_signal *oop_signal_new(oop_source *); +oop_adapter_signal *oop_signal_new_flags(oop_source *, int flags); void oop_signal_delete(oop_adapter_signal *); oop_source *oop_signal_source(oop_adapter_signal *); diff --git a/signal.c b/signal.c index 421ddae16844c2b9dcd5121ed403a477eb09299e..2a16d219297112bcbcfa3f7facf83b5778a165fc 100644 --- a/signal.c +++ b/signal.c @@ -32,6 +32,7 @@ struct oop_adapter_signal { oop_source *source; /* backing source */ struct sig_signal sig[OOP_NUM_SIGNALS]; int num_events; + int use_sa_restart; }; static struct oop_adapter_signal *sig_owner[OOP_NUM_SIGNALS]; @@ -137,6 +138,7 @@ static void sig_on_signal(oop_source *source,int sig, #ifdef SA_NODEFER act.sa_flags &= ~SA_NODEFER; #endif + if (s->use_sa_restart) act.sa_flags |= SA_RESTART; sigaction(sig,&act,NULL); } } @@ -173,7 +175,7 @@ static int fcntl_flag(int fd, int get_op, int set_op, int val) { return fcntl(fd,set_op,flags|val); } -oop_adapter_signal *oop_signal_new(oop_source *source) { +oop_adapter_signal *oop_signal_new_flags(oop_source *source, int flags) { int i; oop_adapter_signal * const s = oop_malloc(sizeof(*s)); if (NULL == s) return NULL; @@ -204,10 +206,18 @@ oop_adapter_signal *oop_signal_new(oop_source *source) { s->sig[i].active = 0; } + if (flags & OOP_SIGNAL_USE_RESTART) { + s->use_sa_restart = 1; + } + s->magic = MAGIC; return s; } +oop_adapter_signal *oop_signal_new(oop_source *source) { + return oop_signal_new_flags(source, 0); +} + void oop_signal_delete(oop_adapter_signal *s) { assert(0 == s->num_events && "cannot delete with signal handler"); s->magic = 0;