00001 
00002 
00003 #include "ace/XtReactor.h"
00004 
00005 #include "ace/SOCK_Acceptor.h"
00006 #include "ace/SOCK_Connector.h"
00007 
00008 ACE_RCSID(ace, XtReactor, "XtReactor.cpp,v 4.40 2006/04/19 11:54:56 jwillemsen Exp")
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                               int 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   int result = ACE_Select_Reactor::register_handler_i (handle,
00207                                                        handler, mask);
00208   if (result == -1)
00209     return -1;
00210 
00211   int condition = 0;
00212 
00213 #if !defined ACE_WIN32
00214   if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::READ_MASK))
00215     ACE_SET_BITS (condition, XtInputReadMask);
00216   if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::WRITE_MASK))
00217     ACE_SET_BITS (condition, XtInputWriteMask);
00218   if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::EXCEPT_MASK))
00219     ACE_SET_BITS (condition, XtInputExceptMask);
00220   if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::ACCEPT_MASK))
00221     ACE_SET_BITS (condition, XtInputReadMask);
00222   if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::CONNECT_MASK)){
00223       ACE_SET_BITS (condition, XtInputWriteMask); 
00224       ACE_SET_BITS (condition, XtInputReadMask);  
00225   }
00226 #else
00227   if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::READ_MASK))
00228     ACE_SET_BITS (condition, XtInputReadWinsock);
00229   if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::WRITE_MASK))
00230     ACE_SET_BITS (condition, XtInputWriteWinsock);
00231   if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::EXCEPT_MASK))
00232     ACE_NOTSUP_RETURN(-1);
00233   if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::ACCEPT_MASK))
00234     ACE_SET_BITS (condition, XtInputReadWinsock);
00235   if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::CONNECT_MASK)){
00236       ACE_SET_BITS (condition, XtInputWriteWinsock); 
00237       ACE_SET_BITS (condition, XtInputReadWinsock);  
00238   }
00239 #endif 
00240 
00241   if (condition != 0)
00242     {
00243       ACE_XtReactorID *XtID = this->ids_;
00244 
00245       while(XtID)
00246         {
00247           if (XtID->handle_ == handle)
00248             {
00249               ::XtRemoveInput (XtID->id_);
00250 
00251               XtID->id_ = ::XtAppAddInput (this->context_,
00252                                            (int) handle,
00253                                            (XtPointer) condition,
00254                                            InputCallbackProc,
00255                                            (XtPointer) this);
00256               return 0;
00257             }
00258           else
00259             XtID = XtID->next_;
00260         }
00261 
00262       ACE_NEW_RETURN (XtID,
00263                       ACE_XtReactorID,
00264                       -1);
00265       XtID->next_ = this->ids_;
00266       XtID->handle_ = handle;
00267       XtID->id_ = ::XtAppAddInput (this->context_,
00268                                   (int) handle,
00269                                   (XtPointer) condition,
00270                                   InputCallbackProc,
00271                                   (XtPointer) this);
00272       this->ids_ = XtID;
00273     }
00274   return 0;
00275 }
00276 
00277 int
00278 ACE_XtReactor::register_handler_i (const ACE_Handle_Set &handles,
00279                                    ACE_Event_Handler *handler,
00280                                    ACE_Reactor_Mask mask)
00281 {
00282   return ACE_Select_Reactor::register_handler_i (handles,
00283                                                  handler,
00284                                                  mask);
00285 }
00286 
00287 int
00288 ACE_XtReactor::remove_handler_i (ACE_HANDLE handle,
00289                                  ACE_Reactor_Mask mask)
00290 {
00291   ACE_TRACE ("ACE_XtReactor::remove_handler_i");
00292 
00293   
00294   
00295   
00296 
00297   
00298   this->remove_XtInput (handle);
00299 
00300   
00301   return ACE_Select_Reactor::remove_handler_i (handle,
00302                                                mask);
00303 }
00304 
00305 void
00306 ACE_XtReactor::remove_XtInput (ACE_HANDLE handle)
00307 {
00308   ACE_TRACE ("ACE_XtReactor::remove_XtInput");
00309 
00310   ACE_XtReactorID *XtID = this->ids_;
00311 
00312   if (XtID)
00313     {
00314       if (XtID->handle_ == handle)
00315         {
00316           ::XtRemoveInput (XtID->id_);
00317           this->ids_ = XtID->next_;
00318           delete XtID;
00319           return;
00320         }
00321 
00322       ACE_XtReactorID *NextID = XtID->next_;
00323 
00324       while (NextID)
00325         {
00326           if (NextID->handle_ == handle)
00327             {
00328               ::XtRemoveInput(NextID->id_);
00329               XtID->next_ = NextID->next_;
00330               delete NextID;
00331               return;
00332             }
00333           else
00334             {
00335               XtID = NextID;
00336               NextID = NextID->next_;
00337             }
00338         }
00339     }
00340 }
00341 
00342 int
00343 ACE_XtReactor::remove_handler_i (const ACE_Handle_Set &handles,
00344                                  ACE_Reactor_Mask mask)
00345 {
00346   return ACE_Select_Reactor::remove_handler_i (handles,
00347                                                mask);
00348 }
00349 
00350 
00351 
00352 
00353 void
00354 ACE_XtReactor::reset_timeout (void)
00355 {
00356   
00357   ACE_ASSERT (this->context_ != 0);
00358 
00359   if (timeout_)
00360     ::XtRemoveTimeOut (timeout_);
00361   timeout_ = 0;
00362 
00363   ACE_Time_Value *max_wait_time =
00364     this->timer_queue_->calculate_timeout (0);
00365 
00366   if (max_wait_time)
00367     timeout_ = ::XtAppAddTimeOut (this->context_,
00368                                   max_wait_time->msec (),
00369                                   TimerCallbackProc,
00370                                   (XtPointer) this);
00371 }
00372 
00373 int
00374 ACE_XtReactor::reset_timer_interval
00375   (long timer_id,
00376    const ACE_Time_Value &interval)
00377 {
00378   ACE_TRACE ("ACE_XtReactor::reset_timer_interval");
00379   ACE_MT (ACE_GUARD_RETURN (ACE_Select_Reactor_Token, ace_mon, this->token_, -1));
00380 
00381   int const result = ACE_Select_Reactor::timer_queue_->reset_interval
00382     (timer_id,
00383      interval);
00384 
00385   if (result == -1)
00386     return -1;
00387   else
00388     {
00389       this->reset_timeout ();
00390       return result;
00391     }
00392 }
00393 
00394 long
00395 ACE_XtReactor::schedule_timer (ACE_Event_Handler *event_handler,
00396                 const void *arg,
00397                 const ACE_Time_Value &delay,
00398                                const ACE_Time_Value &interval)
00399 {
00400   ACE_TRACE ("ACE_XtReactor::schedule_timer");
00401   ACE_MT (ACE_GUARD_RETURN (ACE_Select_Reactor_Token, ace_mon, this->token_, -1));
00402 
00403   long const result = ACE_Select_Reactor::schedule_timer (event_handler,
00404                                                           arg,
00405                                                           delay,
00406                                                           interval);
00407   if (result == -1)
00408     return -1;
00409   else
00410     {
00411       this->reset_timeout ();
00412       return result;
00413     }
00414 }
00415 
00416 int
00417 ACE_XtReactor::cancel_timer (ACE_Event_Handler *handler,
00418                              int dont_call_handle_close)
00419 {
00420   ACE_TRACE ("ACE_XtReactor::cancel_timer");
00421 
00422   if (ACE_Select_Reactor::cancel_timer (handler,
00423                                         dont_call_handle_close) == -1)
00424     return -1;
00425   else
00426     {
00427       this->reset_timeout ();
00428       return 0;
00429     }
00430 }
00431 
00432 int
00433 ACE_XtReactor::cancel_timer (long timer_id,
00434                              const void **arg,
00435                              int dont_call_handle_close)
00436 {
00437   ACE_TRACE ("ACE_XtReactor::cancel_timer");
00438 
00439   if (ACE_Select_Reactor::cancel_timer (timer_id,
00440                                         arg,
00441                                         dont_call_handle_close) == -1)
00442     return -1;
00443   else
00444     {
00445       this->reset_timeout ();
00446       return 0;
00447     }
00448 }
00449 
00450 ACE_END_VERSIONED_NAMESPACE_DECL