00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00026 #include "SignalEvent.hh"
00027 #include "SignalEvent.ih"
00028
00029
00030 #include <senf/Utils/senfassert.hh>
00031 #include <senf/Utils/signalnames.hh>
00032 #include "senf/Utils/IgnoreValue.hh"
00033
00034
00035 #define prefix_
00036
00037
00038 prefix_ senf::scheduler::detail::SignalDispatcher::SignalDispatcher()
00039 : blocked_ (true)
00040 {
00041 if (pipe(sigPipe_) <0)
00042 SENF_THROW_SYSTEM_EXCEPTION("pipe()");
00043 sigemptyset(&sigSet_);
00044 detail::FdManager::instance().set(sigPipe_[0], detail::FdManager::EV_READ, this);
00045 }
00046
00047 prefix_ senf::scheduler::detail::SignalDispatcher::~SignalDispatcher()
00048 {
00049 for (SignalSet::iterator i (handlers_.begin()); i != handlers_.end(); ++i) {
00050 ::signal(i->signal_, SIG_DFL);
00051 detail::FIFORunner::instance().dequeue(&(*i));
00052 }
00053 sigprocmask(SIG_UNBLOCK, &sigSet_, 0);
00054 detail::FdManager::instance().remove(sigPipe_[0]);
00055 close(sigPipe_[0]);
00056 close(sigPipe_[1]);
00057 }
00058
00059 prefix_ void senf::scheduler::detail::SignalDispatcher::add(SignalEvent & event)
00060 {
00061 SignalSet::iterator i (handlers_.find(event));
00062 if (i != handlers_.end())
00063 throw DuplicateSignalRegistrationException()
00064 << " for signal " << signalName(event.signal_) << " (" << event.signal_ << ")";
00065
00066 handlers_.insert(event);
00067 sigaddset(&sigSet_, event.signal_);
00068 detail::FIFORunner::instance().enqueue(&event);
00069
00070 sigset_t sig;
00071 sigemptyset(&sig);
00072 sigaddset(&sig, event.signal_);
00073 sigprocmask(blocked_ ? SIG_BLOCK : SIG_UNBLOCK, &sig, 0);
00074
00075
00076 struct sigaction act;
00077 act.sa_sigaction = &sigHandler;
00078 act.sa_mask = sigSet_;
00079 act.sa_flags = SA_SIGINFO | SA_RESTART;
00080 for (SignalSet::iterator i (handlers_.begin()); i != handlers_.end(); ++i) {
00081 if (i->signal_ == SIGCLD)
00082 act.sa_flags |= SA_NOCLDSTOP;
00083 else
00084 act.sa_flags &= ~SA_NOCLDSTOP;
00085 if (sigaction(i->signal_, &act, 0) < 0)
00086 SENF_THROW_SYSTEM_EXCEPTION("sigaction()");
00087 }
00088 }
00089
00090 prefix_ void senf::scheduler::detail::SignalDispatcher::remove(SignalEvent & event)
00091 {
00092 ::signal(event.signal_, SIG_DFL);
00093 detail::FIFORunner::instance().dequeue(&event);
00094 handlers_.erase(event);
00095 sigset_t sig;
00096 sigemptyset(&sig);
00097 sigaddset(&sig, event.signal_);
00098 sigprocmask(SIG_UNBLOCK, &sig, 0);
00099 }
00100
00101 prefix_ void senf::scheduler::detail::SignalDispatcher::signal(int events)
00102 {
00103 siginfo_t info;
00104 if (read(sigPipe_[0], &info, sizeof(info)) < int(sizeof(info)))
00105 return;
00106 SignalSet::iterator i (handlers_.find(info.si_signo, FindNumericSignal()));
00107 if (i == handlers_.end())
00108 return;
00109 i->siginfo_ = info;
00110 i->setRunnable();
00111 }
00112
00113 prefix_ void senf::scheduler::detail::SignalDispatcher::sigHandler(int signal,
00114 ::siginfo_t * siginfo,
00115 void *)
00116 {
00117 SENF_ASSERT( alive(), "Internal failure: Destroyed signal handler called" );
00118
00119 siginfo->si_signo = signal;
00120
00121 senf::IGNORE( write(instance().sigPipe_[1], siginfo, sizeof(*siginfo)) );
00122 }
00123
00124 prefix_ void senf::scheduler::SignalEvent::v_run()
00125 {
00126 cb_(siginfo_);
00127 }
00128
00129 prefix_ char const * senf::scheduler::SignalEvent::v_type()
00130 const
00131 {
00132 return "si";
00133 }
00134
00135 prefix_ std::string senf::scheduler::SignalEvent::v_info()
00136 const
00137 {
00138 return "";
00139 }
00140
00141
00142 #undef prefix_
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154