4 #ifndef _iqxmlrpc_reactor_impl_h_
5 #define _iqxmlrpc_reactor_impl_h_
11 #include "reactor_poll_impl.h"
14 typedef Reactor_poll_impl ReactorImpl;
17 #include "reactor_select_impl.h"
20 typedef Reactor_select_impl ReactorImpl;
24 #include <boost/utility.hpp>
50 typedef typename Lock::scoped_lock scoped_lock;
51 typedef std::map<Socket::Handler, Event_handler*> EventHandlersMap;
52 typedef EventHandlersMap::iterator h_iterator;
53 typedef HandlerStateList::const_iterator hs_const_iterator;
54 typedef HandlerStateList::iterator hs_iterator;
56 size_t size()
const {
return handlers_states.size(); }
57 hs_const_iterator begin()
const {
return handlers_states.begin(); }
58 hs_iterator begin() {
return handlers_states.begin(); }
59 hs_const_iterator end()
const {
return handlers_states.end(); }
60 hs_iterator end() {
return handlers_states.end(); }
65 void handle_user_events();
66 bool handle_system_events( Timeout );
76 EventHandlersMap handlers;
77 HandlerStateList handlers_states;
79 unsigned num_stoppers;
92 typename Reactor<Lock>::hs_iterator
93 Reactor<Lock>::find_handler_state(Event_handler* eh)
95 return std::find(begin(), end(), HandlerState(eh->get_handler()));
101 scoped_lock lk(lock);
102 h_iterator i = handlers.find(fd);
103 return i == handlers.end() ? NULL : i->second;
106 template <
class Lock>
107 void Reactor<Lock>::register_handler( Event_handler* eh, Event_mask mask )
109 scoped_lock lk(lock);
111 if (eh->is_stopper())
114 Socket::Handler fd = eh->get_handler();
116 if( handlers.find(fd) == handlers.end() )
118 handlers_states.push_back( HandlerState(fd, mask) );
123 typename Reactor<Lock>::hs_iterator i = find_handler_state(eh);
128 template <
class Lock>
129 void Reactor<Lock>::unregister_handler( Event_handler* eh, Event_mask mask )
131 scoped_lock lk(lock);
132 hs_iterator i = find_handler_state( eh );
136 int newmask = (i->mask &= !mask);
140 handlers.erase(eh->get_handler());
141 handlers_states.erase(i);
143 if (eh->is_stopper())
149 template <
class Lock>
150 void Reactor<Lock>::unregister_handler( Event_handler* eh )
152 scoped_lock lk(lock);
153 h_iterator i = handlers.find(eh->get_handler());
155 if( i != handlers.end() )
158 handlers_states.erase(find_handler_state(eh));
160 if (eh->is_stopper())
165 template <
class Lock>
166 void Reactor<Lock>::fake_event( Event_handler* eh, Event_mask mask )
168 scoped_lock lk(lock);
169 hs_iterator i = find_handler_state( eh );
175 template <
class Lock>
176 void Reactor<Lock>::invoke_clients_handler(
177 Event_handler* handler, HandlerState& hs,
bool& terminate )
179 bool in = (hs.revents & Reactor_base::INPUT) != 0;
180 bool out = (hs.revents & Reactor_base::OUTPUT) != 0;
183 handler->handle_input( terminate );
185 handler->handle_output( terminate );
188 template <
class Lock>
189 void Reactor<Lock>::invoke_servers_handler(
190 Event_handler* handler, HandlerState& hs,
bool& terminate )
193 invoke_clients_handler( handler, hs, terminate );
195 catch(
const std::exception& e )
197 handler->log_exception( e );
202 handler->log_unknown_exception();
207 template <
class Lock>
208 void Reactor<Lock>::invoke_event_handler( Reactor_base::HandlerState& hs )
210 bool terminate =
false;
212 Event_handler* handler = find_handler(hs.fd);
215 if( handler->catch_in_reactor() )
216 invoke_servers_handler( handler, hs, terminate );
218 invoke_clients_handler( handler, hs, terminate );
222 unregister_handler( handler );
227 template <
class Lock>
228 void Reactor<Lock>::handle_user_events()
230 HandlerStateList called_by_user;
231 scoped_lock lk(lock);
233 for( hs_iterator i = begin(); i != end(); ++i )
235 if( i->revents && (i->mask | i->revents) )
237 called_by_user.push_back( *i );
238 i->revents &= !i->mask;
244 while( !called_by_user.empty() )
246 HandlerState hs(called_by_user.front());
247 called_by_user.pop_front();
248 invoke_event_handler(hs);
252 template <
class Lock>
253 bool Reactor<Lock>::handle_system_events(Reactor_base::Timeout ms)
255 scoped_lock lk(lock);
256 HandlerStateList tmp(handlers_states);
264 HandlerStateList ret;
265 bool succ = impl.poll(ret, ms);
272 HandlerState hs(ret.front());
274 invoke_event_handler(hs);
280 template <
class Lock>
283 if (handlers.empty())
286 if (handlers.size() - num_stoppers <= 0)
289 handle_user_events();
290 return handle_system_events(ms);