其实信号的注销过程与event的注销过程也很类似, 本篇就不再过多的就行叙述, 将源码注释贴出来即可.
信号注销
evsignal_del 函数
// 信号的注销
int
evsignal_del(struct event *ev)
{
struct event_base *base = ev->ev_base;
struct evsignal_info *sig = &base->sig;
int evsignal = EVENT_SIGNAL(ev);
assert(evsignal >= 0 && evsignal < NSIG);
/* multiple events may listen to the same signal */
// 将信号从对应的信号队列中删除
TAILQ_REMOVE(&sig->evsigevents[evsignal], ev, ev_signal_next);
// 信号为空则返回
if (!TAILQ_EMPTY(&sig->evsigevents[evsignal]))
return (0);
event_debug(("%s: %p: restoring signal handler", __func__, ev));
return (_evsignal_restore_handler(ev->ev_base, EVENT_SIGNAL(ev)));
}
从信号队列中删除, 最后调用_evsignal_restore_handler
函数
_evsignal_restore_handler 函数
// 设置信号的捕捉函数
int
_evsignal_restore_handler(struct event_base *base, int evsignal)
{
int ret = 0;
struct evsignal_info *sig = &base->sig;
#ifdef HAVE_SIGACTION
struct sigaction *sh;
#else
ev_sighandler_t *sh;
#endif
/* restore previous handler */
sh = sig->sh_old[evsignal];
sig->sh_old[evsignal] = NULL;
#ifdef HAVE_SIGACTION
if (sigaction(evsignal, sh, NULL) == -1) {
event_warn("sigaction");
ret = -1;
}
#else
if (signal(evsignal, *sh) == SIG_ERR) {
event_warn("signal");
ret = -1;
}
#endif
free(sh);
return ret;
}
信号数量设置为空, 并释放空间.
evsignal_dealloc 函数
删除evsignal_info
信号结构
void
evsignal_dealloc(struct event_base *base)
{
int i = 0;
// 信号如果加入了主循环中, 则删除该信号
if (base->sig.ev_signal_added) {
event_del(&base->sig.ev_signal);
base->sig.ev_signal_added = 0;
}
// 还原信号
for (i = 0; i < NSIG; ++i) {
if (i < base->sig.sh_old_max && base->sig.sh_old[i] != NULL)
_evsignal_restore_handler(base, i);
}
// 关闭读写端口
if (base->sig.ev_signal_pair[0] != -1) {
EVUTIL_CLOSESOCKET(base->sig.ev_signal_pair[0]);
base->sig.ev_signal_pair[0] = -1;
}
if (base->sig.ev_signal_pair[1] != -1) {
EVUTIL_CLOSESOCKET(base->sig.ev_signal_pair[1]);
base->sig.ev_signal_pair[1] = -1;
}
base->sig.sh_old_max = 0;
/* per index frees are handled in evsig_del() */
if (base->sig.sh_old) {
free(base->sig.sh_old);
base->sig.sh_old = NULL;
}
}