diff options
author | Ronnie Sahlberg <ronniesahlberg@gmail.com> | 2012-04-26 08:09:23 +1000 |
---|---|---|
committer | Ronnie Sahlberg <ronniesahlberg@gmail.com> | 2012-04-26 08:09:23 +1000 |
commit | db411aaada39593c80f92e46be31d3473bf4639f (patch) | |
tree | f68222404db2155cc6d8d3f861ac486cb8a509ae /ctdb/lib/tevent/tevent_signal.c | |
parent | 58e10b280d4a94a812bad07bbca049cddb2c1174 (diff) | |
parent | 195cf3c87e3c6c9f1784aa483110a64bc8760703 (diff) | |
download | samba-db411aaada39593c80f92e46be31d3473bf4639f.tar.gz samba-db411aaada39593c80f92e46be31d3473bf4639f.tar.xz samba-db411aaada39593c80f92e46be31d3473bf4639f.zip |
Merge remote branch 'amitay/tevent-sync'
(This used to be ctdb commit 17ff3f240b0d72c72ed28d70fb9aeb3b20c80670)
Diffstat (limited to 'ctdb/lib/tevent/tevent_signal.c')
-rw-r--r-- | ctdb/lib/tevent/tevent_signal.c | 42 |
1 files changed, 39 insertions, 3 deletions
diff --git a/ctdb/lib/tevent/tevent_signal.c b/ctdb/lib/tevent/tevent_signal.c index c505419a2d..56bcef9150 100644 --- a/ctdb/lib/tevent/tevent_signal.c +++ b/ctdb/lib/tevent/tevent_signal.c @@ -208,7 +208,7 @@ struct tevent_signal *tevent_common_add_signal(struct tevent_context *ev, /* the sig_state needs to be on a global context as it can last across multiple event contexts */ if (sig_state == NULL) { - sig_state = talloc_zero(talloc_autofree_context(), struct tevent_sig_state); + sig_state = talloc_zero(NULL, struct tevent_sig_state); if (sig_state == NULL) { return NULL; } @@ -307,6 +307,15 @@ struct tevent_signal *tevent_common_add_signal(struct tevent_context *ev, return se; } +struct tevent_se_exists { + struct tevent_se_exists **myself; +}; + +static int tevent_se_exists_destructor(struct tevent_se_exists *s) +{ + *s->myself = NULL; + return 0; +} /* check if a signal is pending @@ -335,7 +344,25 @@ int tevent_common_check_signal(struct tevent_context *ev) } for (sl=sig_state->sig_handlers[i];sl;sl=next) { struct tevent_signal *se = sl->se; + struct tevent_se_exists *exists; + next = sl->next; + + /* + * We have to be careful to not touch "se" + * after it was deleted in its handler. Thus + * we allocate a child whose destructor will + * tell by nulling out itself that its parent + * is gone. + */ + exists = talloc(se, struct tevent_se_exists); + if (exists == NULL) { + continue; + } + exists->myself = &exists; + talloc_set_destructor( + exists, tevent_se_exists_destructor); + #ifdef SA_SIGINFO if (se->sa_flags & SA_SIGINFO) { uint32_t j; @@ -352,17 +379,26 @@ int tevent_common_check_signal(struct tevent_context *ev) se->handler(ev, se, i, 1, (void*)&sig_state->sig_info[i][ofs], se->private_data); + if (!exists) { + break; + } } - if (se->sa_flags & SA_RESETHAND) { +#ifdef SA_RESETHAND + if (exists && (se->sa_flags & SA_RESETHAND)) { talloc_free(se); } +#endif + talloc_free(exists); continue; } #endif se->handler(ev, se, i, count, NULL, se->private_data); - if (se->sa_flags & SA_RESETHAND) { +#ifdef SA_RESETHAND + if (exists && (se->sa_flags & SA_RESETHAND)) { talloc_free(se); } +#endif + talloc_free(exists); } #ifdef SA_SIGINFO |