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 FdDispatcher non-inline non-template implementation */
37 //#include "FdEvent.mpp"
39 //-/////////////////////////////////////////////////////////////////////////////////////////////////
41 //-/////////////////////////////////////////////////////////////////////////////////////////////////
42 // senf::scheduler::detail::FdDispatcher
44 prefix_ senf::scheduler::detail::FdDispatcher::~FdDispatcher()
46 for (FdSet::iterator i (fds_.begin()); i != fds_.end(); ++i) {
47 detail::FdManager::instance().remove(i->fd_);
48 detail::FIFORunner::instance().dequeue(&(*i));
52 prefix_ bool senf::scheduler::detail::FdDispatcher::add(FdEvent & event)
54 std::pair<FdSet::iterator,FdSet::iterator> range (fds_.equal_range(event));
56 for (FdSet::iterator i (range.first); i != range.second; ++i)
58 if (event.events_ & events)
59 throw FdEvent::DuplicateEventRegistrationException() << "vinfo: " << event.v_info();
61 if (! detail::FdManager::instance().set(event.fd_, events | event.events_, &event))
64 detail::FIFORunner::instance().enqueue(&event);
65 fds_.insert(range.first, event);
70 prefix_ void senf::scheduler::detail::FdDispatcher::remove(FdEvent & event)
72 fds_.erase(FdSet::current(event));
73 detail::FIFORunner::instance().dequeue(&event);
75 std::pair<FdSet::iterator,FdSet::iterator> range (fds_.equal_range(event));
76 if (range.first == range.second)
77 detail::FdManager::instance().remove(event.fd_);
80 for (FdSet::iterator i (range.first); i != range.second; ++i)
82 detail::FdManager::instance().set(event.fd_, events, &(*range.first));
86 //-/////////////////////////////////////////////////////////////////////////////////////////////////
87 // senf::scheduler::detail::FileDispatcher
89 prefix_ void senf::scheduler::detail::FileDispatcher::add(FdEvent & event)
91 std::pair<FdSet::iterator,FdSet::iterator> range (fds_.equal_range(event));
93 for (FdSet::iterator i (range.first); i != range.second; ++i)
95 if (event.events_ & events)
96 throw FdEvent::DuplicateEventRegistrationException() << "vinfo: " << event.v_info();
98 detail::FIFORunner::instance().enqueue(&event);
99 fds_.insert(range.first, event);
101 detail::FdManager::instance().timeout(0);
104 prefix_ senf::scheduler::detail::FileDispatcher::FileDispatcher()
105 : managerTimeout_ (scheduler::detail::FdManager::instance().timeout())
108 prefix_ senf::scheduler::detail::FileDispatcher::~FileDispatcher()
110 detail::FdManager::instance().timeout(-1);
111 for (FdSet::iterator i (fds_.begin()); i != fds_.end(); ++i)
112 detail::FIFORunner::instance().dequeue(&(*i));
115 prefix_ void senf::scheduler::detail::FileDispatcher::prepareRun()
117 for (FdSet::iterator i (fds_.begin()); i != fds_.end(); ++i) {
118 i->signaledEvents_ = i->events_;
123 prefix_ void senf::scheduler::detail::FileDispatcher::remove(FdEvent & event)
125 fds_.erase(FdSet::current(event));
126 detail::FIFORunner::instance().dequeue(&event);
128 detail::FdManager::instance().timeout(managerTimeout_);
131 //-/////////////////////////////////////////////////////////////////////////////////////////////////
132 // senf::scheduler::FdEvent
134 prefix_ void senf::scheduler::FdEvent::disable()
138 detail::FdDispatcher::instance().remove(*this);
140 detail::FileDispatcher::instance().remove(*this);
144 prefix_ void senf::scheduler::FdEvent::enable()
146 if (! enabled() && events_ && fd_ != -1) {
147 if (pollable_ && detail::FdDispatcher::instance().add(*this))
149 detail::FileDispatcher::instance().add(*this);
154 prefix_ senf::scheduler::FdEvent & senf::scheduler::FdEvent::events(int events)
164 prefix_ void senf::scheduler::FdEvent::signal(int events)
166 detail::FdDispatcher::FdSet::iterator i (detail::FdDispatcher::FdSet::current(*this));
167 detail::FdDispatcher::FdSet::iterator const i_end (detail::FdDispatcher::instance().fds_.end());
168 bool all ((events & (EV_ERR | EV_HUP)) && ! (events & (EV_READ | EV_PRIO | EV_WRITE)));
169 for (; i != i_end && fd_ == i->fd_; ++i) {
170 i->signaledEvents_ = events & (EV_ERR | EV_HUP | i->events_);
171 if (i->events_ & events || all)
176 prefix_ void senf::scheduler::FdEvent::v_run()
178 cb_(signaledEvents_);
181 prefix_ char const * senf::scheduler::FdEvent::v_type()
187 prefix_ std::string senf::scheduler::FdEvent::v_info()
190 std::stringstream ss;
194 ss << " (NOT pollable)";
195 if (events_ & EV_READ)
197 if (events_ & EV_PRIO)
199 if (events_ & EV_WRITE)
204 //-/////////////////////////////////////////////////////////////////////////////////////////////////
206 //#include "FdEvent.mpp"
212 // comment-column: 40
213 // c-file-style: "senf"
214 // indent-tabs-mode: nil
215 // ispell-local-dictionary: "american"
216 // compile-command: "scons -u test"