Merge branch 'event_reinit-for-signals-v3'

* event_reinit-for-signals-v3:
  test/regress: cover existing signal callbacks and fork() + event_reinit()
  test/regress: cover signals after fork() + event_reinit()
  test/regress: main/fork: rewrite assertions by just removing event in callback
  event_reinit: make signals works after fork() without evsig_add()
  event_reinit: always re-init signal's socketpair

Fixes #307
This commit is contained in:
Azat Khuzhin 2015-12-27 16:49:42 +03:00
commit 57e46d3271
2 changed files with 29 additions and 24 deletions

16
event.c
View File

@ -969,13 +969,13 @@ event_reinit(struct event_base *base)
event_del_nolock_(&base->sig.ev_signal, EVENT_DEL_AUTOBLOCK); event_del_nolock_(&base->sig.ev_signal, EVENT_DEL_AUTOBLOCK);
event_debug_unassign(&base->sig.ev_signal); event_debug_unassign(&base->sig.ev_signal);
memset(&base->sig.ev_signal, 0, sizeof(base->sig.ev_signal)); memset(&base->sig.ev_signal, 0, sizeof(base->sig.ev_signal));
if (base->sig.ev_signal_pair[0] != -1)
EVUTIL_CLOSESOCKET(base->sig.ev_signal_pair[0]);
if (base->sig.ev_signal_pair[1] != -1)
EVUTIL_CLOSESOCKET(base->sig.ev_signal_pair[1]);
had_signal_added = 1; had_signal_added = 1;
base->sig.ev_signal_added = 0; base->sig.ev_signal_added = 0;
} }
if (base->sig.ev_signal_pair[0] != -1)
EVUTIL_CLOSESOCKET(base->sig.ev_signal_pair[0]);
if (base->sig.ev_signal_pair[1] != -1)
EVUTIL_CLOSESOCKET(base->sig.ev_signal_pair[1]);
if (base->th_notify_fn != NULL) { if (base->th_notify_fn != NULL) {
was_notifiable = 1; was_notifiable = 1;
base->th_notify_fn = NULL; base->th_notify_fn = NULL;
@ -1024,8 +1024,12 @@ event_reinit(struct event_base *base)
if (evmap_reinit_(base) < 0) if (evmap_reinit_(base) < 0)
res = -1; res = -1;
} else { } else {
if (had_signal_added) res = evsig_init_(base);
res = evsig_init_(base); if (res == 0 && had_signal_added) {
res = event_add_nolock_(&base->sig.ev_signal, NULL, 0);
if (res == 0)
base->sig.ev_signal_added = 1;
}
} }
/* If we were notifiable before, and nothing just exploded, become /* If we were notifiable before, and nothing just exploded, become

View File

@ -817,29 +817,22 @@ end:
} }
#ifndef _WIN32 #ifndef _WIN32
static void signal_cb(evutil_socket_t fd, short event, void *arg);
#define current_base event_global_current_base_ #define current_base event_global_current_base_
extern struct event_base *current_base; extern struct event_base *current_base;
static void static void
child_signal_cb(evutil_socket_t fd, short event, void *arg) fork_signal_cb(evutil_socket_t fd, short events, void *arg)
{ {
struct timeval tv; event_del(arg);
int *pint = arg;
*pint = 1;
tv.tv_usec = 500000;
tv.tv_sec = 0;
event_loopexit(&tv);
} }
static void static void
test_fork(void) test_fork(void)
{ {
int status, got_sigchld = 0; int status;
struct event ev, sig_ev; struct event ev, sig_ev, usr_ev, existing_ev;
pid_t pid; pid_t pid;
setup_test("After fork: "); setup_test("After fork: ");
@ -855,9 +848,12 @@ test_fork(void)
if (event_add(&ev, NULL) == -1) if (event_add(&ev, NULL) == -1)
exit(1); exit(1);
evsignal_set(&sig_ev, SIGCHLD, child_signal_cb, &got_sigchld); evsignal_set(&sig_ev, SIGCHLD, fork_signal_cb, &sig_ev);
evsignal_add(&sig_ev, NULL); evsignal_add(&sig_ev, NULL);
evsignal_set(&existing_ev, SIGUSR2, fork_signal_cb, &existing_ev);
evsignal_add(&existing_ev, NULL);
event_base_assert_ok_(current_base); event_base_assert_ok_(current_base);
TT_BLATHER(("Before fork")); TT_BLATHER(("Before fork"));
if ((pid = regress_fork()) == 0) { if ((pid = regress_fork()) == 0) {
@ -874,6 +870,11 @@ test_fork(void)
evsignal_del(&sig_ev); evsignal_del(&sig_ev);
evsignal_set(&usr_ev, SIGUSR1, fork_signal_cb, &usr_ev);
evsignal_add(&usr_ev, NULL);
raise(SIGUSR1);
raise(SIGUSR2);
called = 0; called = 0;
event_dispatch(); event_dispatch();
@ -915,12 +916,12 @@ test_fork(void)
shutdown(pair[0], SHUT_WR); shutdown(pair[0], SHUT_WR);
event_dispatch(); evsignal_set(&usr_ev, SIGUSR1, fork_signal_cb, &usr_ev);
evsignal_add(&usr_ev, NULL);
raise(SIGUSR1);
raise(SIGUSR2);
if (!got_sigchld) { event_dispatch();
fprintf(stdout, "FAILED (sigchld)\n");
exit(1);
}
evsignal_del(&sig_ev); evsignal_del(&sig_ev);