1 #include "ace/FoxReactor/FoxReactor.h"
3 FXDEFMAP(ACE_FoxReactor
) ACE_FoxReactorMap
[]={
4 FXMAPFUNCS(SEL_IO_READ
,0,MAXKEY
,ACE_FoxReactor::onFileEvents
),
5 FXMAPFUNCS(SEL_IO_WRITE
,0,MAXKEY
,ACE_FoxReactor::onFileEvents
),
6 FXMAPFUNCS(SEL_IO_EXCEPT
,0,MAXKEY
,ACE_FoxReactor::onFileEvents
),
7 FXMAPFUNCS(SEL_TIMEOUT
,0,MAXKEY
,ACE_FoxReactor::onTimerEvents
),
10 FXIMPLEMENT(ACE_FoxReactor
,FXObject
,ACE_FoxReactorMap
,ARRAYNUMBER(ACE_FoxReactorMap
))
12 ACE_ALLOC_HOOK_DEFINE (ACE_FoxReactor
)
14 // Must be called with lock held
15 ACE_FoxReactor::ACE_FoxReactor (FXApp
* a
,
19 : ACE_Select_Reactor (size
, restart
, h
), fxapp(a
)
21 // When the ACE_Select_Reactor is constructed it creates the notify
22 // pipe and registers it with the register_handler_i() method. The
23 // FoxReactor overloads this method BUT because the
24 // register_handler_i occurs when constructing the base class
25 // ACE_Select_Reactor, the ACE_Select_Reactor register_handler_i()
26 // is called not the FoxReactor register_handler_i(). This means
27 // that the notify pipe is registered with the ACE_Select_Reactor
28 // event handling code not the FoxReactor and so notfications don't
29 // work. To get around this we simply close and re-opened the
30 // notification handler in the constructor of the FoxReactor.
32 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
33 this->notify_handler_
->close ();
34 this->notify_handler_
->open (this, 0);
35 #endif /* ACE_MT_SAFE */
38 ACE_FoxReactor::~ACE_FoxReactor ()
42 void ACE_FoxReactor::fxapplication(FXApp
*a
)
47 // This is just the <wait_for_multiple_events> from ace/Reactor.cpp
48 // but we use the Fox functions to wait for an event, not <select>
51 ACE_FoxReactor::wait_for_multiple_events (ACE_Select_Reactor_Handle_Set
&handle_set
,
52 ACE_Time_Value
*max_wait_time
)
54 ACE_TRACE( "ACE_FoxReactor::wait_for_multiple_events" );
59 max_wait_time
= this->timer_queue_
->calculate_timeout (max_wait_time
);
60 size_t width
= this->handler_rep_
.max_handlep1 ();
61 handle_set
.rd_mask_
= this->wait_set_
.rd_mask_
;
62 handle_set
.wr_mask_
= this->wait_set_
.wr_mask_
;
63 handle_set
.ex_mask_
= this->wait_set_
.ex_mask_
;
65 nfound
= FoxWaitForMultipleEvents (width
,
68 } while( nfound
== -1 && this->handle_error () > 0 );
72 #if !defined (ACE_WIN32)
73 handle_set
.rd_mask_
.sync (this->handler_rep_
.max_handlep1 ());
74 handle_set
.wr_mask_
.sync (this->handler_rep_
.max_handlep1 ());
75 handle_set
.ex_mask_
.sync (this->handler_rep_
.max_handlep1 ());
76 #endif /* ACE_WIN32 */
80 // Timed out or input available
84 ACE_FoxReactor::FoxWaitForMultipleEvents (int width
,
85 ACE_Select_Reactor_Handle_Set
&wait_set
,
86 ACE_Time_Value */
*max_wait_time*/
)
88 // Check to make sure our handle's are all usable.
89 ACE_Select_Reactor_Handle_Set temp_set
= wait_set
;
91 if (ACE_OS::select (width
,
95 (ACE_Time_Value
*) &ACE_Time_Value::zero
) == -1)
96 return -1; // Bad file arguments...
99 this->fxapp
->runOneEvent () ;
101 // Reset the width, in case it changed during the upcalls.
102 width
= handler_rep_
.max_handlep1 ();
104 // Now actually read the result needed by the <Select_Reactor> using
106 return ACE_OS::select(width
,
110 (ACE_Time_Value
*) &ACE_Time_Value::zero
);
114 long ACE_FoxReactor::onFileEvents(FXObject
* /* ob */, FXSelector se
, void* handle
){
115 FXSelector sel
=FXSELTYPE(se
);
116 ACE_Select_Reactor_Handle_Set dispatch_set
;
118 if(sel
==SEL_IO_READ
){
119 dispatch_set
.rd_mask_
.set_bit(ACE_HANDLE(reinterpret_cast<FXival
>(handle
)));
123 if(sel
==SEL_IO_WRITE
){
124 dispatch_set
.wr_mask_
.set_bit(ACE_HANDLE(reinterpret_cast<FXival
>(handle
)));
128 if(sel
==SEL_IO_EXCEPT
){
129 dispatch_set
.ex_mask_
.set_bit(ACE_HANDLE(reinterpret_cast<FXival
>(handle
)));
132 if(f
) dispatch (1, dispatch_set
);
137 long ACE_FoxReactor::onTimerEvents(FXObject
* /* ob */, FXSelector
/* sel */, void* /* handle */)
139 // Deal with any timer events
140 ACE_Select_Reactor_Handle_Set handle_set
;
141 this->dispatch (0, handle_set
);
143 // Set next timeout signal
144 this->reset_timeout ();
150 ACE_FoxReactor::register_handler_i (ACE_HANDLE handle
,
151 ACE_Event_Handler
*handler
,
152 ACE_Reactor_Mask mask
)
154 ACE_TRACE ("ACE_FoxReactor::register_handler_i");
156 int const result
= ACE_Select_Reactor::register_handler_i (handle
,
161 unsigned long condition
= 0;
163 if (ACE_BIT_ENABLED (mask
, ACE_Event_Handler::READ_MASK
))
164 ACE_SET_BITS (condition
, FX::INPUT_READ
);
165 if (ACE_BIT_ENABLED (mask
, ACE_Event_Handler::WRITE_MASK
))
166 ACE_SET_BITS (condition
, FX::INPUT_WRITE
);
167 if (ACE_BIT_ENABLED (mask
, ACE_Event_Handler::EXCEPT_MASK
))
168 ACE_SET_BITS (condition
, FX::INPUT_EXCEPT
);
169 if (ACE_BIT_ENABLED (mask
, ACE_Event_Handler::ACCEPT_MASK
))
170 ACE_SET_BITS (condition
, FX::INPUT_READ
);
171 if (ACE_BIT_ENABLED (mask
, ACE_Event_Handler::CONNECT_MASK
))
173 ACE_SET_BITS (condition
, FX::INPUT_WRITE
); // connected, you may write
174 ACE_SET_BITS (condition
, FX::INPUT_READ
); // connected, you have data/err
179 fxapp
->addInput(handle
, condition
, this, 0);
185 ACE_FoxReactor::register_handler_i (const ACE_Handle_Set
&handles
,
186 ACE_Event_Handler
*handler
,
187 ACE_Reactor_Mask mask
)
189 return ACE_Select_Reactor::register_handler_i (handles
, handler
, mask
);
193 ACE_FoxReactor::remove_handler_i (ACE_HANDLE handle
, ACE_Reactor_Mask mask
)
195 ACE_TRACE ("ACE_FoxReactor::remove_handler_i");
197 // In the registration phase we registered first with
198 // ACE_Select_Reactor and then with X. Now we are now doing things
203 if (ACE_BIT_ENABLED (mask
, ACE_Event_Handler::READ_MASK
))
204 ACE_SET_BITS (condition
, FX::INPUT_READ
);
205 if (ACE_BIT_ENABLED (mask
, ACE_Event_Handler::WRITE_MASK
))
206 ACE_SET_BITS (condition
, FX::INPUT_WRITE
);
207 if (ACE_BIT_ENABLED (mask
, ACE_Event_Handler::EXCEPT_MASK
))
208 ACE_SET_BITS (condition
, FX::INPUT_EXCEPT
);
209 if (ACE_BIT_ENABLED (mask
, ACE_Event_Handler::ACCEPT_MASK
))
210 ACE_SET_BITS (condition
, FX::INPUT_READ
);
211 if (ACE_BIT_ENABLED (mask
, ACE_Event_Handler::CONNECT_MASK
))
213 ACE_SET_BITS (condition
, FX::INPUT_WRITE
); // connected, you may write
214 ACE_SET_BITS (condition
, FX::INPUT_READ
); // connected, you have data/err
217 // First clean up the corresponding X11Input.
218 fxapp
->removeInput ((int)handle
,condition
); // ACE_reinterpret_cast(int,handle));
220 // Now let the reactor do its work.
221 return ACE_Select_Reactor::remove_handler_i (handle
, mask
);
225 ACE_FoxReactor::remove_handler_i (const ACE_Handle_Set
&handles
,
226 ACE_Reactor_Mask mask
)
228 return ACE_Select_Reactor::remove_handler_i (handles
, mask
);
231 // The following function ensures there's an Fox timeout for the first
232 // timeout in the Reactor's Timer_Queue.
235 ACE_FoxReactor::reset_timeout ()
237 ACE_Time_Value
*max_wait_time
=
238 this->timer_queue_
->calculate_timeout (0);
240 if (max_wait_time
!= 0)
242 float t
= max_wait_time
->sec () +
243 max_wait_time
->usec () / 1000000.0F
;
244 fxapp
->addTimeout (this, 0, t
*1000);
249 ACE_FoxReactor::reset_timer_interval
251 const ACE_Time_Value
&interval
)
253 ACE_TRACE ("ACE_FoxReactor::reset_timer_interval");
254 ACE_MT (ACE_GUARD_RETURN (ACE_Select_Reactor_Token
, ace_mon
, this->token_
, -1));
257 ACE_Select_Reactor::reset_timer_interval (timer_id
,
264 this->reset_timeout ();
270 ACE_FoxReactor::schedule_timer (ACE_Event_Handler
*event_handler
,
272 const ACE_Time_Value
&delay
,
273 const ACE_Time_Value
&interval
)
275 ACE_TRACE ("ACE_FoxReactor::schedule_timer");
276 ACE_MT (ACE_GUARD_RETURN (ACE_Select_Reactor_Token
, ace_mon
, this->token_
, -1));
278 long result
= ACE_Select_Reactor::schedule_timer (event_handler
,
286 this->reset_timeout ();
292 ACE_FoxReactor::cancel_timer (ACE_Event_Handler
*handler
,
293 int dont_call_handle_close
)
295 ACE_TRACE ("ACE_FoxReactor::cancel_timer");
297 if (ACE_Select_Reactor::cancel_timer (handler
,
298 dont_call_handle_close
) == -1)
302 this->reset_timeout ();
308 ACE_FoxReactor::cancel_timer (long timer_id
,
310 int dont_call_handle_close
)
312 ACE_TRACE ("ACE_FoxReactor::cancel_timer");
314 if (ACE_Select_Reactor::cancel_timer (timer_id
,
316 dont_call_handle_close
) == -1)
320 this->reset_timeout ();