4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at
9 // http://senf.berlios.de/license.html
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on,
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
15 // Software distributed under the License is distributed on an "AS IS" basis,
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
17 // for the specific language governing rights and limitations under the License.
19 // The Original Code is Fraunhofer FOKUS code.
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V.
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
26 // Stefan Bund <g0dil@berlios.de>
29 \brief SignalDispatcher non-inline non-template implementation */
31 #include "SignalEvent.hh"
32 #include "SignalEvent.ih"
35 #include <senf/Utils/senfassert.hh>
36 #include <senf/Utils/signalnames.hh>
37 #include "senf/Utils/IgnoreValue.hh"
39 //#include "SignalEvent.mpp"
41 //-/////////////////////////////////////////////////////////////////////////////////////////////////
43 prefix_ senf::scheduler::detail::SignalDispatcher::SignalDispatcher()
46 if (pipe(sigPipe_) <0)
47 SENF_THROW_SYSTEM_EXCEPTION("pipe()");
48 sigemptyset(&sigSet_);
49 detail::FdManager::instance().set(sigPipe_[0], detail::FdManager::EV_READ, this);
52 prefix_ senf::scheduler::detail::SignalDispatcher::~SignalDispatcher()
54 for (SignalSet::iterator i (handlers_.begin()); i != handlers_.end(); ++i) {
55 ::signal(i->signal_, SIG_DFL);
56 detail::FIFORunner::instance().dequeue(&(*i));
58 sigprocmask(SIG_UNBLOCK, &sigSet_, 0);
59 detail::FdManager::instance().remove(sigPipe_[0]);
64 prefix_ void senf::scheduler::detail::SignalDispatcher::add(SignalEvent & event)
66 SignalSet::iterator i (handlers_.find(event));
67 if (i != handlers_.end())
68 throw DuplicateSignalRegistrationException()
69 << " for signal " << signalName(event.signal_) << " (" << event.signal_ << ")";
71 handlers_.insert(event);
72 sigaddset(&sigSet_, event.signal_);
73 detail::FIFORunner::instance().enqueue(&event);
77 sigaddset(&sig, event.signal_);
78 sigprocmask(blocked_ ? SIG_BLOCK : SIG_UNBLOCK, &sig, 0);
80 // Need to re-register all handlers to update sa_mask
82 act.sa_sigaction = &sigHandler;
83 act.sa_mask = sigSet_;
84 act.sa_flags = SA_SIGINFO | SA_RESTART;
85 for (SignalSet::iterator i (handlers_.begin()); i != handlers_.end(); ++i) {
86 if (i->signal_ == SIGCLD)
87 act.sa_flags |= SA_NOCLDSTOP;
89 act.sa_flags &= ~SA_NOCLDSTOP;
90 if (sigaction(i->signal_, &act, 0) < 0)
91 SENF_THROW_SYSTEM_EXCEPTION("sigaction()");
95 prefix_ void senf::scheduler::detail::SignalDispatcher::remove(SignalEvent & event)
97 ::signal(event.signal_, SIG_DFL);
98 detail::FIFORunner::instance().dequeue(&event);
99 handlers_.erase(event);
102 sigaddset(&sig, event.signal_);
103 sigprocmask(SIG_UNBLOCK, &sig, 0);
106 prefix_ void senf::scheduler::detail::SignalDispatcher::signal(int events)
109 if (read(sigPipe_[0], &info, sizeof(info)) < int(sizeof(info)))
111 SignalSet::iterator i (handlers_.find(info.si_signo, FindNumericSignal()));
112 if (i == handlers_.end())
118 prefix_ void senf::scheduler::detail::SignalDispatcher::sigHandler(int signal,
119 ::siginfo_t * siginfo,
122 SENF_ASSERT( alive(), "Internal failure: Destroyed signal handler called" );
123 // The manpage says, si_signo is unused in linux so we set it here
124 siginfo->si_signo = signal;
125 // We can't do much on error anyway so we ignore errors here
126 senf::IGNORE( write(instance().sigPipe_[1], siginfo, sizeof(*siginfo)) );
129 prefix_ void senf::scheduler::SignalEvent::v_run()
134 prefix_ char const * senf::scheduler::SignalEvent::v_type()
140 prefix_ std::string senf::scheduler::SignalEvent::v_info()
146 //-/////////////////////////////////////////////////////////////////////////////////////////////////
148 //#include "SignalEvent.mpp"
154 // comment-column: 40
155 // c-file-style: "senf"
156 // indent-tabs-mode: nil
157 // ispell-local-dictionary: "american"
158 // compile-command: "scons -u test"