18 #include <boost/multi_index_container.hpp>
19 #include <boost/multi_index/mem_fun.hpp>
20 #include <boost/multi_index/ordered_index.hpp>
21 #include <boost/multi_index/hashed_index.hpp>
37 typedef boost::multi_index_container<
39 boost::multi_index::indexed_by<
40 boost::multi_index::ordered_non_unique<
41 boost::multi_index::const_mem_fun<EventHandler,
const TimeValue &,
43 boost::multi_index::hashed_unique<boost::multi_index::identity<EventHandler*> >
53 running(false), port(),
54 io_handler_count(0), io_events(), event_handlers()
70 EventLoop::EventLoop() SSRC_DECL_THROW(
std::runtime_error) :
77 return _state->event_handlers.size();
81 return _state->io_handler_count;
85 return _state->running;
90 const TimeValue & timeout,
92 SSRC_DECL_THROW(std::runtime_error)
95 if(_state->port.add(handler.event_descriptor(), events, &handler, once)) {
96 if(_state->io_events.size() == _state->io_handler_count)
98 ++_state->io_handler_count;
102 handler._handled_timeout =
false;
103 handler._once = once;
104 handler._timeout = timeout;
106 #if defined(WISP_HAVE_NONPERSISTENT_EVENTS) || defined(WISP_HAVE_KQUEUE)
107 handler._events = events;
113 TimeValue expiration;
114 expiration.now_mono()+=timeout;
115 handler._expiration = expiration;
118 _state->event_handlers.insert(&handler);
123 const bool is_io_event =
133 #if defined(WISP_HAVE_KQUEUE)
137 #elif defined(WISP_HAVE_NONPERSISTENT_EVENTS)
148 if(_state->event_handlers.get<
ByIdentity>().erase(&handler) > 0 &&
151 --_state->io_handler_count;
162 EventPort & port = _state->port;
164 _state->running =
true;
165 while(count_io_handlers() > 0 && _state->running) {
166 int fd_count, timeout = -1;
167 event_handler_container::iterator it = event_handlers.begin();
170 if(io_events.size() != count_io_handlers())
171 io_events.resize(count_io_handlers());
179 timeout = (handler->
expiration() - now).to_milliseconds();
182 fd_count = port.wait(&io_events[0], count_io_handlers(), timeout);
190 info._now = now.now_mono();
192 for(
int i = 0; i < fd_count; ++i) {
193 handler = EventPort::get_handler(io_events[i]);
194 info._io_events = EventPort::get_events(io_events[i]);
195 info._timeout = (handler->
expiration() <= now);
216 handler->_handled_timeout =
true;
217 }
else if(handler->_once) {
218 remove_handler(*handler);
221 #if defined(WISP_HAVE_NONPERSISTENT_EVENTS)
224 if(!handler->_once) {
231 info._timeout =
true;
232 info._io_events = None;
234 it = event_handlers.begin();
235 std::iterator_traits<event_handler_container::iterator>::difference_type
236 count = std::distance(it, event_handlers.upper_bound(now));
240 it = event_handlers.erase(it);
243 if(!handler->_once) {
244 handler->_expiration = now + handler->
timeout();
245 event_handlers.insert(handler);
247 remove_handler(*handler);
249 if(!handler->_handled_timeout)
252 handler->_handled_timeout =
false;
259 _state->running =
false;