00001 #include "ace/TkReactor.h"
00002 
00003 #include "ace/SOCK_Acceptor.h"
00004 #include "ace/SOCK_Connector.h"
00005 
00006 ACE_RCSID(ace, TkReactor, "TkReactor.cpp,v 4.15 2005/10/28 23:55:10 ossama Exp")
00007 
00008 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00009 
00010 ACE_ALLOC_HOOK_DEFINE (ACE_TkReactor)
00011 
00012 
00013 ACE_TkReactor::ACE_TkReactor (size_t size,
00014                               int restart,
00015                               ACE_Sig_Handler *h)
00016   : ACE_Select_Reactor (size, restart, h),
00017     ids_ (0),
00018     timeout_ (0)
00019 {
00020   
00021   
00022   
00023   
00024   
00025   
00026   
00027   
00028   
00029   
00030 
00031 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00032   this->notify_handler_->close ();
00033   this->notify_handler_->open (this, 0);
00034 #endif 
00035 }
00036 
00037 ACE_TkReactor::~ACE_TkReactor (void)
00038 {
00039   
00040 
00041   while (this->ids_)
00042     {
00043       ACE_TkReactorID *TkID = this->ids_->next_;
00044       delete this->ids_;
00045       this->ids_ = TkID;
00046     }
00047 }
00048 
00049 
00050 
00051 
00052 int
00053 ACE_TkReactor::wait_for_multiple_events (ACE_Select_Reactor_Handle_Set &handle_set,
00054                                          ACE_Time_Value *max_wait_time)
00055 {
00056   ACE_TRACE ("ACE_TkReactor::wait_for_multiple_events");
00057   int nfound;
00058 
00059   do
00060     {
00061       max_wait_time = this->timer_queue_->calculate_timeout (max_wait_time);
00062 
00063       size_t width = this->handler_rep_.max_handlep1 ();
00064       handle_set.rd_mask_ = this->wait_set_.rd_mask_;
00065       handle_set.wr_mask_ = this->wait_set_.wr_mask_;
00066       handle_set.ex_mask_ = this->wait_set_.ex_mask_;
00067       nfound = TkWaitForMultipleEvents (width,
00068                                         handle_set,
00069                                         max_wait_time);
00070 
00071     } while (nfound == -1 && this->handle_error () > 0);
00072 
00073   if (nfound > 0)
00074     {
00075 #if !defined (ACE_WIN32)
00076       handle_set.rd_mask_.sync (this->handler_rep_.max_handlep1 ());
00077       handle_set.wr_mask_.sync (this->handler_rep_.max_handlep1 ());
00078       handle_set.ex_mask_.sync (this->handler_rep_.max_handlep1 ());
00079 #endif 
00080     }
00081   return nfound; 
00082 }
00083 
00084 void
00085 ACE_TkReactor::TimerCallbackProc (ClientData cd)
00086 {
00087   ACE_TkReactor *self = (ACE_TkReactor *) cd;
00088   self->timeout_ = 0;
00089 
00090   
00091   ACE_Select_Reactor_Handle_Set handle_set;
00092   self->dispatch (0, handle_set);
00093   self->reset_timeout ();
00094 }
00095 
00096 
00097 
00098 
00099 
00100 
00101 
00102 
00103 
00104 void
00105 ACE_TkReactor::InputCallbackProc (ClientData cd,
00106                                   int )
00107 {
00108   ACE_TkReactor_Input_Callback *callback = (ACE_TkReactor_Input_Callback *) cd;
00109   ACE_TkReactor *self = callback->reactor_;
00110   ACE_HANDLE handle = callback->handle_;
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 (handle + 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_TkReactor::TkWaitForMultipleEvents (int width,
00150                                         ACE_Select_Reactor_Handle_Set &wait_set,
00151                                         ACE_Time_Value *)
00152 {
00153   
00154   ACE_Select_Reactor_Handle_Set temp_set = wait_set;
00155 
00156   if (ACE_OS::select (width,
00157                       temp_set.rd_mask_,
00158                       temp_set.wr_mask_,
00159                       temp_set.ex_mask_,
00160                       (ACE_Time_Value *) &ACE_Time_Value::zero) == -1)
00161     return -1; 
00162 
00163   
00164   
00165 
00166   
00167   ::Tcl_DoOneEvent (0);
00168 
00169   
00170   width = this->handler_rep_.max_handlep1 ();
00171 
00172   
00173   
00174   return ACE_OS::select (width,
00175                          wait_set.rd_mask_,
00176                          wait_set.wr_mask_,
00177                          wait_set.ex_mask_,
00178                          (ACE_Time_Value *) &ACE_Time_Value::zero);
00179 }
00180 
00181 int
00182 ACE_TkReactor::register_handler_i (ACE_HANDLE handle,
00183                                    ACE_Event_Handler *handler,
00184                                    ACE_Reactor_Mask mask)
00185 {
00186   ACE_TRACE ("ACE_TkReactor::register_handler_i");
00187 
00188   int result = ACE_Select_Reactor::register_handler_i (handle,
00189                                                        handler, mask);
00190   if (result == -1)
00191     return -1;
00192 
00193   int condition = 0;
00194 
00195 #if !defined ACE_WIN32
00196   if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::READ_MASK))
00197     ACE_SET_BITS (condition, TK_READABLE);
00198   if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::WRITE_MASK))
00199     ACE_SET_BITS (condition, TK_WRITABLE);
00200   if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::EXCEPT_MASK))
00201     ACE_SET_BITS (condition, TK_EXCEPTION);
00202   if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::ACCEPT_MASK))
00203     ACE_SET_BITS (condition, TK_READABLE);
00204   if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::CONNECT_MASK)){
00205       ACE_SET_BITS (condition, TK_READABLE); 
00206       ACE_SET_BITS (condition, TK_WRITABLE);  
00207   }
00208 #else
00209   if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::READ_MASK))
00210     ACE_SET_BITS (condition, TK_READABLE);
00211   if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::WRITE_MASK))
00212     ACE_SET_BITS (condition, TK_WRITABLE);
00213   if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::EXCEPT_MASK))
00214     ACE_NOTSUP_RETURN(-1);
00215   if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::ACCEPT_MASK))
00216     ACE_SET_BITS (condition, TK_READABLE);
00217   if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::CONNECT_MASK)){
00218       ACE_SET_BITS (condition, TK_READABLE); 
00219       ACE_SET_BITS (condition, TK_WRITABLE);  
00220   }
00221 #endif 
00222 
00223   if (condition != 0)
00224     {
00225       ACE_TkReactorID *TkID = this->ids_;
00226 
00227       while(TkID)
00228         {
00229           if (TkID->handle_ == handle)
00230             {
00231               ::Tk_DeleteFileHandler (TkID->handle_);
00232 
00233               ACE_TkReactor_Input_Callback *callback;
00234               ACE_NEW_RETURN (callback,
00235                               ACE_TkReactor_Input_Callback,
00236                               -1);
00237               callback->reactor_ = this;
00238               callback->handle_ = handle;
00239               ::Tk_CreateFileHandler ((int) handle,
00240                                       condition,
00241                                       InputCallbackProc,
00242                                       (ClientData) callback);
00243               return 0;
00244             }
00245           else
00246             TkID = TkID->next_;
00247         }
00248 
00249       ACE_NEW_RETURN (TkID,
00250                       ACE_TkReactorID,
00251                       -1);
00252       TkID->next_ = this->ids_;
00253       TkID->handle_ = handle;
00254       ACE_TkReactor_Input_Callback *callback;
00255       ACE_NEW_RETURN (callback,
00256                       ACE_TkReactor_Input_Callback,
00257                       -1);
00258       callback->reactor_ = this;
00259       callback->handle_ = handle;
00260 
00261       ::Tk_CreateFileHandler ((int) handle,
00262                               condition,
00263                               InputCallbackProc,
00264                               (ClientData) callback);
00265       this->ids_ = TkID;
00266     }
00267   return 0;
00268 }
00269 
00270 int
00271 ACE_TkReactor::register_handler_i (const ACE_Handle_Set &handles,
00272                                    ACE_Event_Handler *handler,
00273                                    ACE_Reactor_Mask mask)
00274 {
00275   return ACE_Select_Reactor::register_handler_i (handles,
00276                                                  handler,
00277                                                  mask);
00278 }
00279 
00280 int
00281 ACE_TkReactor::remove_handler_i (ACE_HANDLE handle,
00282                                  ACE_Reactor_Mask mask)
00283 {
00284   ACE_TRACE ("ACE_TkReactor::remove_handler_i");
00285 
00286   
00287   
00288   
00289 
00290   
00291   this->remove_TkFileHandler (handle);
00292 
00293   
00294   return ACE_Select_Reactor::remove_handler_i (handle,
00295                                                mask);
00296 }
00297 
00298 void
00299 ACE_TkReactor::remove_TkFileHandler (ACE_HANDLE handle)
00300 {
00301   ACE_TRACE ("ACE_TkReactor::remove_TkFileHandler");
00302 
00303   ACE_TkReactorID *TkID = this->ids_;
00304 
00305   if (TkID)
00306     {
00307       if (TkID->handle_ == handle)
00308         {
00309           ::Tk_DeleteFileHandler (TkID->handle_);
00310           this->ids_ = TkID->next_;
00311           delete TkID;
00312           return;
00313         }
00314 
00315       ACE_TkReactorID *NextID = TkID->next_;
00316 
00317       while (NextID)
00318         {
00319           if (NextID->handle_ == handle)
00320             {
00321               ::Tk_DeleteFileHandler (NextID->handle_);
00322               TkID->next_ = NextID->next_;
00323               delete NextID;
00324               return;
00325             }
00326           else
00327             {
00328               TkID = NextID;
00329               NextID = NextID->next_;
00330             }
00331         }
00332     }
00333 }
00334 
00335 int
00336 ACE_TkReactor::remove_handler_i (const ACE_Handle_Set &handles,
00337                                  ACE_Reactor_Mask mask)
00338 {
00339   return ACE_Select_Reactor::remove_handler_i (handles,
00340                                                mask);
00341 }
00342 
00343 
00344 
00345 
00346 void
00347 ACE_TkReactor::reset_timeout (void)
00348 {
00349   if (this->timeout_)
00350     ::Tk_DeleteTimerHandler (this->timeout_);
00351   timeout_ = 0;
00352 
00353   ACE_Time_Value *max_wait_time =
00354     this->timer_queue_->calculate_timeout (0);
00355 
00356   if (max_wait_time)
00357     timeout_ = ::Tk_CreateTimerHandler (max_wait_time->msec (),
00358                                         TimerCallbackProc,
00359                                         (ClientData) this);
00360 }
00361 
00362 int
00363 ACE_TkReactor::reset_timer_interval
00364   (long timer_id,
00365    const ACE_Time_Value &interval)
00366 {
00367   ACE_TRACE ("ACE_TkReactor::reset_timer_interval");
00368   ACE_MT (ACE_GUARD_RETURN (ACE_Select_Reactor_Token, ace_mon, this->token_, -1));
00369 
00370   int result = ACE_Select_Reactor::timer_queue_->reset_interval
00371     (timer_id,
00372      interval);
00373 
00374   if (result == -1)
00375     return -1;
00376   else
00377     {
00378       this->reset_timeout ();
00379       return result;
00380     }
00381 }
00382 
00383 long
00384 ACE_TkReactor::schedule_timer (ACE_Event_Handler *event_handler,
00385                                const void *arg,
00386                 const ACE_Time_Value &delay,
00387                                const ACE_Time_Value &interval)
00388 {
00389   ACE_TRACE ("ACE_TkReactor::schedule_timer");
00390   ACE_MT (ACE_GUARD_RETURN (ACE_Select_Reactor_Token, ace_mon, this->token_, -1));
00391 
00392   long result = ACE_Select_Reactor::schedule_timer (event_handler,
00393                                                     arg,
00394                                                     delay,
00395                                                     interval);
00396   if (result == -1)
00397     return -1;
00398   else
00399     {
00400       this->reset_timeout ();
00401       return result;
00402     }
00403 }
00404 
00405 int
00406 ACE_TkReactor::cancel_timer (ACE_Event_Handler *handler,
00407                              int dont_call_handle_close)
00408 {
00409   ACE_TRACE ("ACE_TkReactor::cancel_timer");
00410 
00411   if (ACE_Select_Reactor::cancel_timer (handler,
00412                                         dont_call_handle_close) == -1)
00413     return -1;
00414   else
00415     {
00416       this->reset_timeout ();
00417       return 0;
00418     }
00419 }
00420 
00421 int
00422 ACE_TkReactor::cancel_timer (long timer_id,
00423                              const void **arg,
00424                              int dont_call_handle_close)
00425 {
00426   ACE_TRACE ("ACE_TkReactor::cancel_timer");
00427 
00428   if (ACE_Select_Reactor::cancel_timer (timer_id,
00429                                         arg,
00430                                         dont_call_handle_close) == -1)
00431     return -1;
00432   else
00433     {
00434       this->reset_timeout ();
00435       return 0;
00436     }
00437 }
00438 
00439 ACE_END_VERSIONED_NAMESPACE_DECL