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