00001 /* -*- C++ -*- */ 00002 00003 //============================================================================= 00004 /** 00005 * @file Reactor_Impl.h 00006 * 00007 * $Id: Reactor_Impl.h,v 1.1.1.4 2003/02/21 18:36:32 chad Exp $ 00008 * 00009 * @author Irfan Pyarali 00010 */ 00011 //============================================================================= 00012 00013 00014 #ifndef ACE_REACTOR_IMPL_H 00015 #define ACE_REACTOR_IMPL_H 00016 #include "ace/pre.h" 00017 00018 // Timer Queue is a complicated template class. A simple forward 00019 // declaration will not work 00020 #include "ace/Timer_Queue.h" 00021 00022 #if !defined (ACE_LACKS_PRAGMA_ONCE) 00023 # pragma once 00024 #endif /* ACE_LACKS_PRAGMA_ONCE */ 00025 00026 // Event_Handler.h contains the definition of ACE_Reactor_Mask 00027 #include "ace/Event_Handler.h" 00028 00029 // We are using 4 or 5 signal classes, we could forward declare 00030 // them.... But Timer_Queue_T.h includes Signal.h, so I don't think 00031 // forward declaration will be useful here 00032 #include "ace/Signal.h" 00033 00034 // Forward decls 00035 class ACE_Handle_Set; 00036 class ACE_Reactor_Impl; 00037 00038 /** 00039 * @class ACE_Reactor_Notify 00040 * 00041 * @brief Abstract class for unblocking an <ACE_Reactor_Impl> from its 00042 * event loop. 00043 */ 00044 class ACE_Export ACE_Reactor_Notify : public ACE_Event_Handler 00045 { 00046 public: 00047 // = Initialization and termination methods. 00048 virtual int open (ACE_Reactor_Impl *, 00049 ACE_Timer_Queue *timer_queue = 0, 00050 int disable_notify = 0) = 0; 00051 virtual int close (void) = 0; 00052 00053 /** 00054 * Called by a thread when it wants to unblock the <Reactor_Impl>. 00055 * This wakeups the <Reactor_Impl> if currently blocked. Pass over 00056 * both the <Event_Handler> *and* the <mask> to allow the caller to 00057 * dictate which <Event_Handler> method the <Reactor_Impl> will 00058 * invoke. The <ACE_Time_Value> indicates how long to blocking 00059 * trying to notify the <Reactor_Impl>. If <timeout> == 0, the 00060 * caller will block until action is possible, else will wait until 00061 * the relative time specified in *<timeout> elapses). 00062 */ 00063 virtual int notify (ACE_Event_Handler * = 0, 00064 ACE_Reactor_Mask = ACE_Event_Handler::EXCEPT_MASK, 00065 ACE_Time_Value * = 0) = 0; 00066 00067 /// Handles pending threads (if any) that are waiting to unblock the 00068 /// <Reactor_Impl>. 00069 virtual int dispatch_notifications (int &number_of_active_handles, 00070 ACE_Handle_Set &rd_mask) = 0; 00071 00072 /// Returns the ACE_HANDLE of the notify pipe on which the reactor 00073 /// is listening for notifications so that other threads can unblock 00074 /// the <Reactor_Impl> 00075 virtual ACE_HANDLE notify_handle (void) = 0; 00076 00077 /// Verify whether the buffer has dispatchable info or not. 00078 virtual int is_dispatchable (ACE_Notification_Buffer &buffer)= 0; 00079 00080 /// Handle one of the notify call on the <handle>. This could be 00081 /// because of a thread trying to unblock the <Reactor_Impl> 00082 virtual int dispatch_notify (ACE_Notification_Buffer &buffer) = 0; 00083 00084 /// Read one of the notify call on the <handle> into the 00085 /// <buffer>. This could be because of a thread trying to unblock 00086 /// the <Reactor_Impl> 00087 virtual int read_notify_pipe (ACE_HANDLE handle, 00088 ACE_Notification_Buffer &buffer) = 0; 00089 /** 00090 * Set the maximum number of times that the <handle_input> method 00091 * will iterate and dispatch the <ACE_Event_Handlers> that are 00092 * passed in via the notify queue before breaking out of the event 00093 * loop. By default, this is set to -1, which means "iterate until 00094 * the queue is empty." Setting this to a value like "1 or 2" will 00095 * increase "fairness" (and thus prevent starvation) at the expense 00096 * of slightly higher dispatching overhead. 00097 */ 00098 virtual void max_notify_iterations (int) = 0; 00099 00100 /** 00101 * Get the maximum number of times that the <handle_input> method 00102 * will iterate and dispatch the <ACE_Event_Handlers> that are 00103 * passed in via the notify queue before breaking out of its event 00104 * loop. 00105 */ 00106 virtual int max_notify_iterations (void) = 0; 00107 00108 /** 00109 * Purge any notifications pending in this reactor for the specified 00110 * <ACE_Event_Handler> object. Returns the number of notifications 00111 * purged. Returns -1 on error. 00112 */ 00113 virtual int purge_pending_notifications (ACE_Event_Handler * = 0, 00114 ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK) = 0; 00115 00116 /// Dump the state of an object. 00117 virtual void dump (void) const = 0; 00118 }; 00119 00120 /** 00121 * @class ACE_Reactor_Impl 00122 * 00123 * @brief An abstract class for implementing the Reactor Pattern. 00124 */ 00125 class ACE_Export ACE_Reactor_Impl 00126 { 00127 public: 00128 /// Close down and release all resources. 00129 virtual ~ACE_Reactor_Impl (void) {} 00130 00131 /// Initialization. 00132 virtual int open (size_t size, 00133 int restart = 0, 00134 ACE_Sig_Handler * = 0, 00135 ACE_Timer_Queue * = 0, 00136 int disable_notify_pipe = 0, 00137 ACE_Reactor_Notify * = 0) = 0; 00138 00139 /** 00140 * Returns 0, if the size of the current message has been put in 00141 * <size> Returns -1, if not. ACE_HANDLE allows the reactor to 00142 * check if the caller is valid. 00143 */ 00144 virtual int current_info (ACE_HANDLE, size_t & /* size */) = 0; 00145 00146 /// Use a user specified signal handler instead. 00147 virtual int set_sig_handler (ACE_Sig_Handler *signal_handler) = 0; 00148 00149 /// @deprecated The following method is deprecated. Use <timer_queue> instead. 00150 /// Set a user specified timer queue. 00151 virtual int set_timer_queue (ACE_Timer_Queue *tq) = 0; 00152 00153 /// Set a user-specified timer queue. 00154 virtual int timer_queue (ACE_Timer_Queue *tq) = 0; 00155 00156 /// Return the current <ACE_Timer_Queue>. 00157 virtual ACE_Timer_Queue *timer_queue (void) const = 0; 00158 00159 /// Close down and release all resources. 00160 virtual int close (void) = 0; 00161 00162 // = Event loop drivers. 00163 /** 00164 * Returns non-zero if there are I/O events "ready" for dispatching, 00165 * but does not actually dispatch the event handlers. By default, 00166 * don't block while checking this, i.e., "poll". 00167 */ 00168 virtual int work_pending (const ACE_Time_Value &max_wait_time = ACE_Time_Value::zero) = 0; 00169 00170 /** 00171 * This event loop driver blocks for up to <max_wait_time> before 00172 * returning. It will return earlier if events occur. Note that 00173 * <max_wait_time> can be 0, in which case this method blocks 00174 * indefinitely until events occur. 00175 * 00176 * <max_wait_time> is decremented to reflect how much time this call 00177 * took. For instance, if a time value of 3 seconds is passed to 00178 * handle_events and an event occurs after 2 seconds, 00179 * <max_wait_time> will equal 1 second. This can be used if an 00180 * application wishes to handle events for some fixed amount of 00181 * time. 00182 * 00183 * Returns the total number of <ACE_Event_Handler>s that were 00184 * dispatched, 0 if the <max_wait_time> elapsed without dispatching 00185 * any handlers, or -1 if an error occurs. 00186 * 00187 * The only difference between <alertable_handle_events> and 00188 * <handle_events> is that in the alertable case, the eventloop will 00189 * return when the system queues an I/O completion routine or an 00190 * Asynchronous Procedure Call. 00191 */ 00192 virtual int handle_events (ACE_Time_Value *max_wait_time = 0) = 0; 00193 virtual int alertable_handle_events (ACE_Time_Value *max_wait_time = 0) = 0; 00194 00195 /** 00196 * This method is just like the one above, except the 00197 * <max_wait_time> value is a reference and can therefore never be 00198 * NULL. 00199 * 00200 * The only difference between <alertable_handle_events> and 00201 * <handle_events> is that in the alertable case, the eventloop will 00202 * return when the system queues an I/O completion routine or an 00203 * Asynchronous Procedure Call. 00204 */ 00205 virtual int handle_events (ACE_Time_Value &max_wait_time) = 0; 00206 virtual int alertable_handle_events (ACE_Time_Value &max_wait_time) = 0; 00207 00208 // = Event handling control. 00209 00210 /** 00211 * Return the status of Reactor. If this function returns 0, the reactor is 00212 * actively handling events. If it returns non-zero, <handling_events> and 00213 * <handle_alertable_events> return -1 immediately. 00214 */ 00215 virtual int deactivated (void) = 0; 00216 00217 /** 00218 * Control whether the Reactor will handle any more incoming events or not. 00219 * If <do_stop> == 1, the Reactor will be disabled. By default, a reactor 00220 * is in active state and can be deactivated/reactived as wish. 00221 */ 00222 virtual void deactivate (int do_stop) = 0; 00223 00224 // = Register and remove Handlers. 00225 00226 /// Register <event_handler> with <mask>. The I/O handle will always 00227 /// come from <get_handle> on the <event_handler>. 00228 virtual int register_handler (ACE_Event_Handler *event_handler, 00229 ACE_Reactor_Mask mask) = 0; 00230 00231 /// Register <event_handler> with <mask>. The I/O handle is provided 00232 /// through the <io_handle> parameter. 00233 virtual int register_handler (ACE_HANDLE io_handle, 00234 ACE_Event_Handler *event_handler, 00235 ACE_Reactor_Mask mask) = 0; 00236 00237 #if defined (ACE_WIN32) 00238 00239 // Originally this interface was available for all platforms, but 00240 // because ACE_HANDLE is an int on non-Win32 platforms, compilers 00241 // are not able to tell the difference between 00242 // register_handler(ACE_Event_Handler*,ACE_Reactor_Mask) and 00243 // register_handler(ACE_Event_Handler*,ACE_HANDLE). Therefore, we 00244 // have restricted this method to Win32 only. 00245 00246 /** 00247 * Register an <event_handler> that will be notified when 00248 * <event_handle> is signaled. Since no event mask is passed 00249 * through this interface, it is assumed that the <event_handle> 00250 * being passed in is an event handle and not an I/O handle. 00251 */ 00252 virtual int register_handler (ACE_Event_Handler *event_handler, 00253 ACE_HANDLE event_handle = ACE_INVALID_HANDLE) = 0; 00254 00255 #endif /* ACE_WIN32 */ 00256 00257 /** 00258 * Register an <event_handler> that will be notified when 00259 * <event_handle> is signaled. <mask> specifies the network events 00260 * that the <event_handler> is interested in. 00261 */ 00262 virtual int register_handler (ACE_HANDLE event_handle, 00263 ACE_HANDLE io_handle, 00264 ACE_Event_Handler *event_handler, 00265 ACE_Reactor_Mask mask) = 0; 00266 00267 /// Register <event_handler> with all the <handles> in the <Handle_Set>. 00268 virtual int register_handler (const ACE_Handle_Set &handles, 00269 ACE_Event_Handler *event_handler, 00270 ACE_Reactor_Mask mask) = 0; 00271 00272 /** 00273 * Register <new_sh> to handle the signal <signum> using the 00274 * <new_disp>. Returns the <old_sh> that was previously registered 00275 * (if any), along with the <old_disp> of the signal handler. 00276 */ 00277 virtual int register_handler (int signum, 00278 ACE_Event_Handler *new_sh, 00279 ACE_Sig_Action *new_disp = 0, 00280 ACE_Event_Handler **old_sh = 0, 00281 ACE_Sig_Action *old_disp = 0) = 0; 00282 00283 /// Registers <new_sh> to handle a set of signals <sigset> using the 00284 /// <new_disp>. 00285 virtual int register_handler (const ACE_Sig_Set &sigset, 00286 ACE_Event_Handler *new_sh, 00287 ACE_Sig_Action *new_disp = 0) = 0; 00288 00289 /** 00290 * Removes <event_handler>. Note that the I/O handle will be 00291 * obtained using <get_handle> method of <event_handler> . If 00292 * <mask> == <ACE_Event_Handler::DONT_CALL> then the <handle_close> 00293 * method of the <event_handler> is not invoked. 00294 */ 00295 virtual int remove_handler (ACE_Event_Handler *event_handler, 00296 ACE_Reactor_Mask mask) = 0; 00297 00298 /** 00299 * Removes <handle>. If <mask> == <ACE_Event_Handler::DONT_CALL> 00300 * then the <handle_close> method of the associated <event_handler> 00301 * is not invoked. 00302 */ 00303 virtual int remove_handler (ACE_HANDLE handle, 00304 ACE_Reactor_Mask mask) = 0; 00305 00306 /** 00307 * Removes all handles in <handle_set>. If <mask> == 00308 * <ACE_Event_Handler::DONT_CALL> then the <handle_close> method of 00309 * the associated <event_handler>s is not invoked. 00310 */ 00311 virtual int remove_handler (const ACE_Handle_Set &handle_set, 00312 ACE_Reactor_Mask mask) = 0; 00313 00314 /** 00315 * Remove the ACE_Event_Handler currently associated with <signum>. 00316 * Install the new disposition (if given) and return the previous 00317 * disposition (if desired by the caller). Returns 0 on success and 00318 * -1 if <signum> is invalid. 00319 */ 00320 virtual int remove_handler (int signum, 00321 ACE_Sig_Action *new_disp, 00322 ACE_Sig_Action *old_disp = 0, 00323 int sigkey = -1) = 0; 00324 00325 /// Calls <remove_handler> for every signal in <sigset>. 00326 virtual int remove_handler (const ACE_Sig_Set &sigset) = 0; 00327 00328 // = Suspend and resume Handlers. 00329 00330 /// Suspend <event_handler> temporarily. Use 00331 /// <ACE_Event_Handler::get_handle> to get the handle. 00332 virtual int suspend_handler (ACE_Event_Handler *event_handler) = 0; 00333 00334 /// Suspend <handle> temporarily. 00335 virtual int suspend_handler (ACE_HANDLE handle) = 0; 00336 00337 /// Suspend all <handles> in handle set temporarily. 00338 virtual int suspend_handler (const ACE_Handle_Set &handles) = 0; 00339 00340 /// Suspend all <handles> temporarily. 00341 virtual int suspend_handlers (void) = 0; 00342 00343 /// Resume <event_handler>. Use <ACE_Event_Handler::get_handle> to 00344 /// get the handle. 00345 virtual int resume_handler (ACE_Event_Handler *event_handler) = 0; 00346 00347 /// Resume <handle>. 00348 virtual int resume_handler (ACE_HANDLE handle) = 0; 00349 00350 /// Resume all <handles> in handle set. 00351 virtual int resume_handler (const ACE_Handle_Set &handles) = 0; 00352 00353 /// Resume all <handles>. 00354 virtual int resume_handlers (void) = 0; 00355 00356 /// Does the reactor allow the application to resume the handle on 00357 /// its own ie. can it pass on the control of handle resumption to 00358 /// the application 00359 virtual int resumable_handler (void) = 0; 00360 00361 /// Return 1 if we any event associations were made by the reactor 00362 /// for the handles that it waits on, 0 otherwise. 00363 virtual int uses_event_associations (void) = 0; 00364 00365 // If we need to reset handles returned from accept/connect. 00366 00367 // = Timer management. 00368 00369 /** 00370 * Schedule an ACE_Event_Handler that will expire after an amount 00371 * of time. The return value of this method, a timer_id value, 00372 * uniquely identifies the event_handler in the ACE_Reactor's 00373 * internal list of timers. 00374 * This timer_id value can be used to cancel the timer 00375 * with the cancel_timer() call. 00376 * 00377 * @see cancel_timer() 00378 * @see reset_timer_interval() 00379 * 00380 * @param event_handler event handler to schedule on reactor 00381 * @param arg argument passed to the handle_timeout() method of event_handler 00382 * @param delay time interval after which the timer will expire 00383 * @param interval time interval after which the timer will be automatically rescheduled 00384 * @return -1 on failure, a timer_id value on success 00385 */ 00386 virtual long schedule_timer (ACE_Event_Handler *event_handler, 00387 const void *arg, 00388 const ACE_Time_Value &delay, 00389 const ACE_Time_Value &interval = ACE_Time_Value::zero) = 0; 00390 00391 /** 00392 * Resets the interval of the timer represented by <timer_id> to 00393 * <interval>, which is specified in relative time to the current 00394 * <gettimeofday>. If <interval> is equal to 00395 * <ACE_Time_Value::zero>, the timer will become a non-rescheduling 00396 * timer. Returns 0 if successful, -1 if not. 00397 */ 00398 virtual int reset_timer_interval (long timer_id, 00399 const ACE_Time_Value &interval) = 0; 00400 00401 /// Cancel all Event_Handlers that match the address of 00402 /// <event_handler>. Returns number of handlers cancelled. 00403 virtual int cancel_timer (ACE_Event_Handler *event_handler, 00404 int dont_call_handle_close = 1) = 0; 00405 00406 /** 00407 * Cancel the single Event_Handler that matches the <timer_id> value 00408 * (which was returned from the schedule method). If arg is 00409 * non-NULL then it will be set to point to the ``magic cookie'' 00410 * argument passed in when the Event_Handler was registered. This 00411 * makes it possible to free up the memory and avoid memory leaks. 00412 * Returns 1 if cancellation succeeded and 0 if the <timer_id> 00413 * wasn't found. 00414 */ 00415 virtual int cancel_timer (long timer_id, 00416 const void **arg = 0, 00417 int dont_call_handle_close = 1) = 0; 00418 00419 // = High-level Event_Handler scheduling operations 00420 00421 /// Add <masks_to_be_added> to the <event_handler>'s entry. 00422 /// <event_handler> must already have been registered. 00423 virtual int schedule_wakeup (ACE_Event_Handler *event_handler, 00424 ACE_Reactor_Mask masks_to_be_added) = 0; 00425 00426 /// Add <masks_to_be_added> to the <handle>'s entry. <event_handler> 00427 /// associated with <handle> must already have been registered. 00428 virtual int schedule_wakeup (ACE_HANDLE handle, 00429 ACE_Reactor_Mask masks_to_be_added) = 0; 00430 00431 /// Clear <masks_to_be_cleared> from the <event_handler>'s entry. 00432 virtual int cancel_wakeup (ACE_Event_Handler *event_handler, 00433 ACE_Reactor_Mask masks_to_be_cleared) = 0; 00434 00435 /// Clear <masks_to_be_cleared> from the <handle>'s entry. 00436 virtual int cancel_wakeup (ACE_HANDLE handle, 00437 ACE_Reactor_Mask masks_to_be_cleared) = 0; 00438 00439 // = Notification methods. 00440 00441 /** 00442 * Notify <event_handler> of <mask> event. The <ACE_Time_Value> 00443 * indicates how long to blocking trying to notify. If <timeout> == 00444 * 0, the caller will block until action is possible, else will wait 00445 * until the relative time specified in <timeout> elapses). 00446 */ 00447 virtual int notify (ACE_Event_Handler *event_handler = 0, 00448 ACE_Reactor_Mask mask = ACE_Event_Handler::EXCEPT_MASK, 00449 ACE_Time_Value * = 0) = 0; 00450 00451 /** 00452 * Set the maximum number of times that ACE_Reactor_Impl will 00453 * iterate and dispatch the <ACE_Event_Handlers> that are passed in 00454 * via the notify queue before breaking out of its 00455 * <ACE_Message_Queue::dequeue> loop. By default, this is set to 00456 * -1, which means "iterate until the queue is empty." Setting this 00457 * to a value like "1 or 2" will increase "fairness" (and thus 00458 * prevent starvation) at the expense of slightly higher dispatching 00459 * overhead. 00460 */ 00461 virtual void max_notify_iterations (int) = 0; 00462 00463 /** 00464 * Get the maximum number of times that the ACE_Reactor_Impl will 00465 * iterate and dispatch the <ACE_Event_Handlers> that are passed in 00466 * via the notify queue before breaking out of its 00467 * <ACE_Message_Queue::dequeue> loop. 00468 */ 00469 virtual int max_notify_iterations (void) = 0; 00470 00471 /** 00472 * Purge any notifications pending in this reactor for the specified 00473 * <ACE_Event_Handler> object. Returns the number of notifications 00474 * purged. Returns -1 on error. 00475 */ 00476 virtual int purge_pending_notifications (ACE_Event_Handler * = 0, 00477 ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK) = 0; 00478 00479 /** 00480 * Check to see if <handle> is associated with a valid Event_Handler 00481 * bound to <mask>. Return the <event_handler> associated with this 00482 * <handler> if <event_handler> != 0. 00483 */ 00484 virtual int handler (ACE_HANDLE handle, 00485 ACE_Reactor_Mask mask, 00486 ACE_Event_Handler **event_handler = 0) = 0; 00487 00488 /** 00489 * Check to see if <signum> is associated with a valid Event_Handler 00490 * bound to a signal. Return the <event_handler> associated with 00491 * this <handler> if <event_handler> != 0. 00492 */ 00493 virtual int handler (int signum, 00494 ACE_Event_Handler ** = 0) = 0; 00495 00496 /// Returns true if Reactor has been successfully initialized, else 00497 /// false. 00498 virtual int initialized (void) = 0; 00499 00500 /// Returns the current size of the Reactor's internal descriptor 00501 /// table. 00502 virtual size_t size (void) const = 0; 00503 00504 /// Returns a reference to the Reactor's internal lock. 00505 virtual ACE_Lock &lock (void) = 0; 00506 00507 /// Wake up all threads in waiting in the event loop 00508 virtual void wakeup_all_threads (void) = 0; 00509 00510 /// Transfers ownership of Reactor_Impl to the <new_owner>. 00511 virtual int owner (ACE_thread_t new_owner, ACE_thread_t *old_owner = 0) = 0; 00512 00513 /// Return the ID of the "owner" thread. 00514 virtual int owner (ACE_thread_t *owner) = 0; 00515 00516 /// Get the existing restart value. 00517 virtual int restart (void) = 0; 00518 00519 /// Set a new value for restart and return the original value. 00520 virtual int restart (int r) = 0; 00521 00522 /// Set position of the owner thread. 00523 virtual void requeue_position (int) = 0; 00524 00525 /// Get position of the owner thread. 00526 virtual int requeue_position (void) = 0; 00527 00528 // = Low-level wait_set mask manipulation methods. 00529 00530 /// GET/SET/ADD/CLR the dispatch mask "bit" bound with the 00531 /// <event_handler> and <mask>. 00532 virtual int mask_ops (ACE_Event_Handler *event_handler, 00533 ACE_Reactor_Mask mask, 00534 int ops) = 0; 00535 00536 /// GET/SET/ADD/CLR the dispatch MASK "bit" bound with the <handle> 00537 /// and <mask>. 00538 virtual int mask_ops (ACE_HANDLE handle, 00539 ACE_Reactor_Mask mask, 00540 int ops) = 0; 00541 00542 // = Low-level ready_set mask manipulation methods. 00543 /// GET/SET/ADD/CLR the ready "bit" bound with the <event_handler> 00544 /// and <mask>. 00545 virtual int ready_ops (ACE_Event_Handler *event_handler, 00546 ACE_Reactor_Mask mask, 00547 int ops) = 0; 00548 00549 /// GET/SET/ADD/CLR the ready "bit" bound with the <handle> and <mask>. 00550 virtual int ready_ops (ACE_HANDLE handle, 00551 ACE_Reactor_Mask, 00552 int ops) = 0; 00553 00554 /// Dump the state of an object. 00555 virtual void dump (void) const = 0; 00556 00557 /// Declare the dynamic allocation hooks. 00558 ACE_ALLOC_HOOK_DECLARE; 00559 }; 00560 00561 #include "ace/post.h" 00562 #endif /* ACE_REACTOR_IMPL_H */
1.2.14 written by Dimitri van Heesch,
© 1997-2002