SignalEvent.cc
Go to the documentation of this file.
1 //
2 // Copyright (c) 2020 Fraunhofer Institute for Applied Information Technology (FIT)
3 // Network Research Group (NET)
4 // Schloss Birlinghoven, 53754 Sankt Augustin, GERMANY
5 // Contact: support@wiback.org
6 //
7 // This file is part of the SENF code tree.
8 // It is licensed under the 3-clause BSD License (aka New BSD License).
9 // See LICENSE.txt in the top level directory for details or visit
10 // https://opensource.org/licenses/BSD-3-Clause
11 //
12 
13 
17 #include "SignalEvent.hh"
18 #include "SignalEvent.ih"
19 
20 // Custom includes
21 #include <senf/Utils/senfassert.hh>
24 
25 //#include "SignalEvent.mpp"
26 #define prefix_
27 //-/////////////////////////////////////////////////////////////////////////////////////////////////
28 
29 prefix_ senf::scheduler::detail::SignalDispatcher::SignalDispatcher()
30  : blocked_ (true)
31 {
32  if (pipe(sigPipe_) < 0)
34  sigemptyset(&sigSet_);
35  detail::FdManager::instance().set(sigPipe_[0], detail::FdManager::EV_READ, this);
36 }
37 
38 prefix_ senf::scheduler::detail::SignalDispatcher::~SignalDispatcher()
39 {
40  for (SignalSet::iterator i (handlers_.begin()); i != handlers_.end(); ++i) {
41  ::signal(i->signal_, SIG_DFL);
42  detail::FIFORunner::instance().dequeue(&(*i));
43  }
44  sigprocmask(SIG_UNBLOCK, &sigSet_, 0);
45  detail::FdManager::instance().remove(sigPipe_[0]);
46  close(sigPipe_[0]);
47  close(sigPipe_[1]);
48 }
49 
50 prefix_ void senf::scheduler::detail::SignalDispatcher::add(SignalEvent & event)
51 {
52  SignalSet::iterator i (handlers_.find(event));
53  if (i != handlers_.end())
54  throw DuplicateSignalRegistrationException()
55  << " for signal " << signalName(event.signal_) << " (" << event.signal_ << ")";
56 
57  handlers_.insert(event);
58  sigaddset(&sigSet_, event.signal_);
59  detail::FIFORunner::instance().enqueue(&event);
60 
61  sigset_t sig;
62  sigemptyset(&sig);
63  sigaddset(&sig, event.signal_);
64  sigprocmask(blocked_ ? SIG_BLOCK : SIG_UNBLOCK, &sig, 0);
65 
66  // Need to re-register all handlers to update sa_mask
67  struct sigaction act;
68  act.sa_sigaction = &sigHandler;
69  act.sa_mask = sigSet_;
70  act.sa_flags = SA_SIGINFO | SA_RESTART;
71  for (SignalSet::iterator i (handlers_.begin()); i != handlers_.end(); ++i) {
72  if (i->signal_ == SIGCHLD)
73  act.sa_flags |= SA_NOCLDSTOP;
74  else
75  act.sa_flags &= ~SA_NOCLDSTOP;
76  if (sigaction(i->signal_, &act, 0) < 0)
77  SENF_THROW_SYSTEM_EXCEPTION("sigaction()");
78  }
79 }
80 
81 prefix_ void senf::scheduler::detail::SignalDispatcher::remove(SignalEvent & event)
82 {
83  ::signal(event.signal_, SIG_DFL);
84  detail::FIFORunner::instance().dequeue(&event);
85  handlers_.erase(event);
86  sigset_t sig;
87  sigemptyset(&sig);
88  sigaddset(&sig, event.signal_);
89  sigprocmask(SIG_UNBLOCK, &sig, 0);
90 }
91 
92 prefix_ void senf::scheduler::detail::SignalDispatcher::signal(int events)
93 {
94  siginfo_t info;
95  if (read(sigPipe_[0], &info, sizeof(info)) < int(sizeof(info)))
96  return;
97  SignalSet::iterator i (handlers_.find(info.si_signo, FindNumericSignal()));
98  if (i == handlers_.end())
99  return;
100  i->siginfo_ = info;
101  i->setRunnable();
102 }
103 
104 prefix_ void senf::scheduler::detail::SignalDispatcher::sigHandler(int signal,
105  ::siginfo_t * siginfo,
106  void *)
107 {
108  SENF_ASSERT( alive(), "Internal failure: Destroyed signal handler called" );
109  // The manpage says, si_signo is unused in linux so we set it here
110  siginfo->si_signo = signal;
111  // We can't do much on error anyway so we ignore errors here
112  senf::IGNORE( write(instance().sigPipe_[1], siginfo, sizeof(*siginfo)) );
113 }
114 
115 prefix_ void senf::scheduler::SignalEvent::v_run()
116 {
117  cb_(siginfo_);
118 }
119 
120 prefix_ char const * senf::scheduler::SignalEvent::v_type()
121  const
122 {
123  return "si";
124 }
125 
126 prefix_ std::string senf::scheduler::SignalEvent::v_info()
127  const
128 {
129  return "";
130 }
131 
132 //-/////////////////////////////////////////////////////////////////////////////////////////////////
133 #undef prefix_
134 //#include "SignalEvent.mpp"
135 
136 
137 // Local Variables:
138 // mode: c++
139 // fill-column: 100
140 // comment-column: 40
141 // c-file-style: "senf"
142 // indent-tabs-mode: nil
143 // ispell-local-dictionary: "american"
144 // compile-command: "scons -u test"
145 // End:
#define SENF_THROW_SYSTEM_EXCEPTION(desc)
#define prefix_
Definition: SignalEvent.cc:26
StatsDataCollectorKernel signal
SignalDispatcher public header.
#define SENF_ASSERT(x, comment)
std::string const & signalName(int signal)
virtual void close()