00001
00002
00003 #include "ace/XtReactor/XtReactor.h"
00004
00005 #include "ace/SOCK_Acceptor.h"
00006 #include "ace/SOCK_Connector.h"
00007
00008 ACE_RCSID(ace, XtReactor, "$Id: XtReactor.cpp 88506 2010-01-13 03:27:48Z schmidt $")
00009
00010 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00011
00012 ACE_ALLOC_HOOK_DEFINE (ACE_XtReactor)
00013
00014
00015 ACE_XtReactor::ACE_XtReactor (XtAppContext context,
00016 size_t size,
00017 bool restart,
00018 ACE_Sig_Handler *h)
00019 : ACE_Select_Reactor (size, restart, h),
00020 context_ (context),
00021 ids_ (0),
00022 timeout_ (0)
00023 {
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00036 this->notify_handler_->close ();
00037 this->notify_handler_->open (this, 0);
00038 #endif
00039 }
00040
00041 ACE_XtReactor::~ACE_XtReactor (void)
00042 {
00043
00044
00045 while (this->ids_)
00046 {
00047 ACE_XtReactorID *XtID = this->ids_->next_;
00048 delete this->ids_;
00049 this->ids_ = XtID;
00050 }
00051 }
00052
00053
00054
00055
00056 int
00057 ACE_XtReactor::wait_for_multiple_events (ACE_Select_Reactor_Handle_Set &handle_set,
00058 ACE_Time_Value *max_wait_time)
00059 {
00060 ACE_TRACE ("ACE_XtReactor::wait_for_multiple_events");
00061 int nfound;
00062
00063 do
00064 {
00065 max_wait_time = this->timer_queue_->calculate_timeout (max_wait_time);
00066
00067 size_t width = this->handler_rep_.max_handlep1 ();
00068 handle_set.rd_mask_ = this->wait_set_.rd_mask_;
00069 handle_set.wr_mask_ = this->wait_set_.wr_mask_;
00070 handle_set.ex_mask_ = this->wait_set_.ex_mask_;
00071 nfound = XtWaitForMultipleEvents (width,
00072 handle_set,
00073 max_wait_time);
00074
00075 } while (nfound == -1 && this->handle_error () > 0);
00076
00077 if (nfound > 0)
00078 {
00079 #if !defined (ACE_WIN32)
00080 handle_set.rd_mask_.sync (this->handler_rep_.max_handlep1 ());
00081 handle_set.wr_mask_.sync (this->handler_rep_.max_handlep1 ());
00082 handle_set.ex_mask_.sync (this->handler_rep_.max_handlep1 ());
00083 #endif
00084 }
00085 return nfound;
00086 }
00087
00088 void
00089 ACE_XtReactor::TimerCallbackProc (XtPointer closure, XtIntervalId * )
00090 {
00091 ACE_XtReactor *self = (ACE_XtReactor *) closure;
00092 self->timeout_ = 0;
00093
00094
00095 ACE_Select_Reactor_Handle_Set handle_set;
00096 self->dispatch (0, handle_set);
00097 self->reset_timeout ();
00098 }
00099
00100
00101
00102
00103
00104 void
00105 ACE_XtReactor::InputCallbackProc (XtPointer closure,
00106 int *source,
00107 XtInputId *)
00108 {
00109 ACE_XtReactor *self = (ACE_XtReactor *) closure;
00110 ACE_HANDLE handle = (ACE_HANDLE) *source;
00111
00112
00113 ACE_Time_Value zero = ACE_Time_Value::zero;
00114
00115 ACE_Select_Reactor_Handle_Set wait_set;
00116
00117
00118
00119
00120 if (self->wait_set_.rd_mask_.is_set (handle))
00121 wait_set.rd_mask_.set_bit (handle);
00122 if (self->wait_set_.wr_mask_.is_set (handle))
00123 wait_set.wr_mask_.set_bit (handle);
00124 if (self->wait_set_.ex_mask_.is_set (handle))
00125 wait_set.ex_mask_.set_bit (handle);
00126
00127 int result = ACE_OS::select (*source + 1,
00128 wait_set.rd_mask_,
00129 wait_set.wr_mask_,
00130 wait_set.ex_mask_, &zero);
00131
00132 ACE_Select_Reactor_Handle_Set dispatch_set;
00133
00134
00135 if (result > 0)
00136 {
00137 if (wait_set.rd_mask_.is_set (handle))
00138 dispatch_set.rd_mask_.set_bit (handle);
00139 if (wait_set.wr_mask_.is_set (handle))
00140 dispatch_set.wr_mask_.set_bit (handle);
00141 if (wait_set.ex_mask_.is_set (handle))
00142 dispatch_set.ex_mask_.set_bit (handle);
00143
00144 self->dispatch (1, dispatch_set);
00145 }
00146 }
00147
00148 int
00149 ACE_XtReactor::XtWaitForMultipleEvents (int width,
00150 ACE_Select_Reactor_Handle_Set &wait_set,
00151 ACE_Time_Value *)
00152 {
00153
00154 ACE_ASSERT (this->context_ != 0);
00155
00156
00157 ACE_Select_Reactor_Handle_Set temp_set = wait_set;
00158
00159 if (ACE_OS::select (width,
00160 temp_set.rd_mask_,
00161 temp_set.wr_mask_,
00162 temp_set.ex_mask_,
00163 (ACE_Time_Value *) &ACE_Time_Value::zero) == -1)
00164 return -1;
00165
00166
00167
00168
00169
00170 ::XtAppProcessEvent (this->context_, XtIMAll);
00171
00172
00173 width = this->handler_rep_.max_handlep1 ();
00174
00175
00176
00177 return ACE_OS::select (width,
00178 wait_set.rd_mask_,
00179 wait_set.wr_mask_,
00180 wait_set.ex_mask_,
00181 (ACE_Time_Value *) &ACE_Time_Value::zero);
00182 }
00183
00184 XtAppContext
00185 ACE_XtReactor::context (void) const
00186 {
00187 return this->context_;
00188 }
00189
00190 void
00191 ACE_XtReactor::context (XtAppContext context)
00192 {
00193 this->context_ = context;
00194 }
00195
00196 int
00197 ACE_XtReactor::register_handler_i (ACE_HANDLE handle,
00198 ACE_Event_Handler *handler,
00199 ACE_Reactor_Mask mask)
00200 {
00201 ACE_TRACE ("ACE_XtReactor::register_handler_i");
00202
00203
00204 ACE_ASSERT (this->context_ != 0);
00205
00206 #if defined ACE_WIN32
00207
00208 if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::EXCEPT_MASK))
00209 ACE_NOTSUP_RETURN(-1);
00210 #endif
00211
00212 int result = ACE_Select_Reactor::register_handler_i (handle,
00213 handler, mask);
00214 if (result == -1)
00215 return -1;
00216
00217 synchronize_XtInput (handle);
00218 return 0;
00219 }
00220
00221 int
00222 ACE_XtReactor::register_handler_i (const ACE_Handle_Set &handles,
00223 ACE_Event_Handler *handler,
00224 ACE_Reactor_Mask mask)
00225 {
00226 return ACE_Select_Reactor::register_handler_i (handles,
00227 handler,
00228 mask);
00229 }
00230
00231 int
00232 ACE_XtReactor::remove_handler_i (ACE_HANDLE handle,
00233 ACE_Reactor_Mask mask)
00234 {
00235 ACE_TRACE ("ACE_XtReactor::remove_handler_i");
00236
00237 int result = ACE_Select_Reactor::remove_handler_i (handle,
00238 mask);
00239 if (result == -1)
00240 return -1;
00241
00242 synchronize_XtInput (handle);
00243 return 0;
00244 }
00245
00246 int
00247 ACE_XtReactor::remove_handler_i (const ACE_Handle_Set &handles,
00248 ACE_Reactor_Mask mask)
00249 {
00250 return ACE_Select_Reactor::remove_handler_i (handles,
00251 mask);
00252 }
00253
00254 int
00255 ACE_XtReactor::suspend_i (ACE_HANDLE handle)
00256 {
00257 ACE_TRACE ("ACE_XtReactor::suspend_i");
00258
00259 int result = ACE_Select_Reactor::suspend_i (handle);
00260
00261 if (result == -1)
00262 return -1;
00263
00264 synchronize_XtInput (handle);
00265 return 0;
00266 }
00267
00268 int
00269 ACE_XtReactor::resume_i (ACE_HANDLE handle)
00270 {
00271 ACE_TRACE ("ACE_XtReactor::resume_i");
00272
00273 int result = ACE_Select_Reactor::resume_i (handle);
00274
00275 if (result == -1)
00276 return -1;
00277
00278 synchronize_XtInput (handle);
00279 return 0;
00280 }
00281
00282 void
00283 ACE_XtReactor::synchronize_XtInput(ACE_HANDLE handle)
00284 {
00285 ACE_TRACE ("ACE_XtReactor::synchronize_XtInput");
00286
00287
00288
00289
00290
00291
00292 ACE_XtReactorID **XtID = &(this->ids_);
00293
00294 while (*XtID && (*XtID)->handle_ != handle)
00295 XtID = &((*XtID)->next_);
00296
00297
00298 if (*XtID)
00299 ::XtRemoveInput ((*XtID)->id_);
00300
00301 int condition = compute_Xt_condition (handle);
00302
00303 if (condition == 0)
00304 {
00305 if (*XtID)
00306 {
00307
00308 ACE_XtReactorID *toDelete = *XtID;
00309 *XtID = (*XtID)->next_;
00310 delete toDelete;
00311 }
00312 return;
00313 }
00314
00315 if (*XtID == 0)
00316 {
00317
00318 ACE_XtReactorID *tmp = new ACE_XtReactorID;
00319 tmp->next_ = this->ids_;
00320 tmp->handle_ = handle;
00321 this->ids_ = tmp;
00322 XtID = &(this->ids_);
00323 }
00324
00325
00326 (*XtID)->id_ = ::XtAppAddInput (this->context_,
00327 (int) handle,
00328 (XtPointer) condition,
00329 InputCallbackProc,
00330 (XtPointer) this);
00331 }
00332
00333 int
00334 ACE_XtReactor::compute_Xt_condition(ACE_HANDLE handle)
00335 {
00336 ACE_TRACE ("ACE_XtReactor::compute_Xt_condition");
00337
00338
00339
00340
00341 int mask =this->bit_ops(handle,
00342 0,
00343 this->wait_set_,
00344 ACE_Reactor::GET_MASK);
00345
00346 if (mask == -1)
00347 return 0;
00348
00349 int condition = 0;
00350
00351 #if !defined ACE_WIN32
00352 if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::READ_MASK))
00353 ACE_SET_BITS (condition, XtInputReadMask);
00354 if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::WRITE_MASK))
00355 ACE_SET_BITS (condition, XtInputWriteMask);
00356 if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::EXCEPT_MASK))
00357 ACE_SET_BITS (condition, XtInputExceptMask);
00358 #else
00359 if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::READ_MASK))
00360 ACE_SET_BITS (condition, XtInputReadWinsock);
00361 if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::WRITE_MASK))
00362 ACE_SET_BITS (condition, XtInputWriteWinsock);
00363
00364
00365 #endif
00366
00367 return condition;
00368 }
00369
00370
00371
00372
00373 void
00374 ACE_XtReactor::reset_timeout (void)
00375 {
00376
00377 ACE_ASSERT (this->context_ != 0);
00378
00379 if (timeout_)
00380 ::XtRemoveTimeOut (timeout_);
00381 timeout_ = 0;
00382
00383 ACE_Time_Value *max_wait_time =
00384 this->timer_queue_->calculate_timeout (0);
00385
00386 if (max_wait_time)
00387 timeout_ = ::XtAppAddTimeOut (this->context_,
00388 max_wait_time->msec (),
00389 TimerCallbackProc,
00390 (XtPointer) this);
00391 }
00392
00393 int
00394 ACE_XtReactor::reset_timer_interval
00395 (long timer_id,
00396 const ACE_Time_Value &interval)
00397 {
00398 ACE_TRACE ("ACE_XtReactor::reset_timer_interval");
00399 ACE_MT (ACE_GUARD_RETURN (ACE_Select_Reactor_Token, ace_mon, this->token_, -1));
00400
00401 int const result = ACE_Select_Reactor::timer_queue_->reset_interval
00402 (timer_id,
00403 interval);
00404
00405 if (result == -1)
00406 return -1;
00407 else
00408 {
00409 this->reset_timeout ();
00410 return result;
00411 }
00412 }
00413
00414 long
00415 ACE_XtReactor::schedule_timer (ACE_Event_Handler *event_handler,
00416 const void *arg,
00417 const ACE_Time_Value &delay,
00418 const ACE_Time_Value &interval)
00419 {
00420 ACE_TRACE ("ACE_XtReactor::schedule_timer");
00421 ACE_MT (ACE_GUARD_RETURN (ACE_Select_Reactor_Token, ace_mon, this->token_, -1));
00422
00423 long const result = ACE_Select_Reactor::schedule_timer (event_handler,
00424 arg,
00425 delay,
00426 interval);
00427 if (result == -1)
00428 return -1;
00429 else
00430 {
00431 this->reset_timeout ();
00432 return result;
00433 }
00434 }
00435
00436 int
00437 ACE_XtReactor::cancel_timer (ACE_Event_Handler *handler,
00438 int dont_call_handle_close)
00439 {
00440 ACE_TRACE ("ACE_XtReactor::cancel_timer");
00441
00442 if (ACE_Select_Reactor::cancel_timer (handler,
00443 dont_call_handle_close) == -1)
00444 return -1;
00445 else
00446 {
00447 this->reset_timeout ();
00448 return 0;
00449 }
00450 }
00451
00452 int
00453 ACE_XtReactor::cancel_timer (long timer_id,
00454 const void **arg,
00455 int dont_call_handle_close)
00456 {
00457 ACE_TRACE ("ACE_XtReactor::cancel_timer");
00458
00459 if (ACE_Select_Reactor::cancel_timer (timer_id,
00460 arg,
00461 dont_call_handle_close) == -1)
00462 return -1;
00463 else
00464 {
00465 this->reset_timeout ();
00466 return 0;
00467 }
00468 }
00469
00470 ACE_END_VERSIONED_NAMESPACE_DECL