forked from lizhenghn123/CppLanguagePrograms
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSignalHandler.cpp
More file actions
101 lines (86 loc) · 2.41 KB
/
SignalHandler.cpp
File metadata and controls
101 lines (86 loc) · 2.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include "net/SignalHandler.h"
#include <sys/signalfd.h>
#include <signal.h>
#include "net/Channel.h"
#include "base/ZLog.h"
NAMESPACE_ZL_NET_START
SignalHandler::SignalHandler(EventLoop *loop)
: loop_(loop), signalFd_(-1), sigFdChannel_(NULL)
{
}
SignalHandler::~SignalHandler()
{
}
void SignalHandler::setSigHandler(int sig, const SignalCallback& handler)
{
sigHanhlers_[sig] = handler;
}
void SignalHandler::removeSig(int sig)
{
SigHandlerMap::iterator iter = sigHanhlers_.find(sig);
if(iter != sigHanhlers_.end())
sigHanhlers_.erase(iter);
}
bool SignalHandler::haveSignal(int sig)
{
return sigHanhlers_.find(sig) != sigHanhlers_.end() ? true : false;
}
int SignalHandler::registerAll()
{
if(signalFd_ > 0)
return 0;
sigset_t mask;
sigemptyset(&mask);
for(SigHandlerMap::iterator iter = sigHanhlers_.begin(); iter != sigHanhlers_.end(); ++iter)
{
sigaddset(&mask, iter->first);
}
// 阻塞信号以使得它们不被默认的处理试方式处理
if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
{
perror("sigprocmask");
return -1;
}
signalFd_ = signalfd(-1, &mask, SFD_NONBLOCK | SFD_CLOEXEC);
if (signalFd_ == -1)
{
perror("signalfd error");
switch(errno)
{
case EBADF: //fd 文件描述符不是一个有效的文件描述符
case EINVAL: //flags 无效; 或者,在 2.6.26 及其前,flags 非零
case EMFILE: //达到单个进程打开的文件描述上限
case ENFILE: //达到可打开文件个数的系统全局上限
case ENODEV: //不能挂载(内部)匿名结点设备
case ENOMEM: //没有足够的内存来创建新的 signalfd 文件描述符
break;
}
return -1;
}
sigFdChannel_ = new Channel(loop_, signalFd_);
sigFdChannel_->setReadCallback(std::bind(&SignalHandler::sigOnRead, this));
sigFdChannel_->enableReading();
return 0;
}
void SignalHandler::sigOnRead()
{
struct signalfd_siginfo fdsi;
ssize_t n = ::read(signalFd_, &fdsi, sizeof(struct signalfd_siginfo));
if (n != sizeof(struct signalfd_siginfo))
{
LOG_INFO("SignalHandler::sigOnRead : read signal error[%d][%d]", n, errno);
}
int signo = fdsi.ssi_signo;
if(haveSignal(signo))
{
if(sigHanhlers_[signo])
sigHanhlers_[signo](signo);
else
LOG_INFO("SignalHandler::sigOnRead : signal[%d] have not set callback", signo);
}
else
{
LOG_INFO("SignalHandler::sigOnRead : read unexpected signal[%d]", signo);
}
}
NAMESPACE_ZL_NET_END