00001 // -*- C++ -*- 00002 00003 // ========================================================================= 00004 /** 00005 * @file Dev_Poll_Reactor.h 00006 * 00007 * $Id: Dev_Poll_Reactor.h,v 1.1.1.1 2003/02/21 18:36:32 chad Exp $ 00008 * 00009 * EXPERIMENTAL /dev/poll (or Linux /dev/epoll) based Reactor 00010 * implementation. 00011 * 00012 * @author Ossama Othman <ossama@uci.edu> 00013 */ 00014 // ========================================================================= 00015 00016 00017 #ifndef ACE_DEV_POLL_REACTOR_H 00018 #define ACE_DEV_POLL_REACTOR_H 00019 00020 #include "ace/pre.h" 00021 00022 #include "ace/Reactor_Impl.h" 00023 00024 #if !defined (ACE_LACKS_PRAGMA_ONCE) 00025 # pragma once 00026 #endif /* ACE_LACKS_PRAGMA_ONCE */ 00027 00028 00029 #if defined (ACE_HAS_EVENT_POLL) && defined (ACE_HAS_DEV_POLL) 00030 # error ACE_HAS_EVENT_POLL and ACE_HAS_DEV_POLL are mutually exclusive. 00031 #endif /* ACE_HAS_EVENT_POLL && defined ACE_HAS_DEV_POLL */ 00032 00033 00034 #if defined (ACE_HAS_EVENT_POLL) || defined (ACE_HAS_DEV_POLL) 00035 00036 #include "ace/Pipe.h" 00037 00038 // Forward declarations 00039 class ACE_Sig_Handler; 00040 class ACE_Dev_Poll_Reactor; 00041 00042 /** 00043 * @class ACE_Dev_Poll_Event_Tuple 00044 * 00045 * @brief Class that associates specific event mask with a given event 00046 * handler. 00047 * 00048 * This class merely provides a means to associate an event mask 00049 * with an event handler. Such an association is needed since it is 00050 * not possible to retrieve the event mask from the "interest set" 00051 * stored in the `/dev/poll' or `/dev/epoll' driver. Without this 00052 * external association, it would not be possible keep track of the 00053 * event mask for a given event handler when suspending it or resuming 00054 * it. 00055 * 00056 * @note An ACE_Handle_Set is not used since the number of handles may 00057 * exceed its capacity (ACE_DEFAULT_SELECT_REACTOR_SIZE). 00058 */ 00059 class ACE_Dev_Poll_Event_Tuple 00060 { 00061 public: 00062 00063 /// Constructor. 00064 ACE_Dev_Poll_Event_Tuple (void); 00065 00066 public: 00067 00068 /// The event handler. 00069 ACE_Event_Handler *event_handler; 00070 00071 /// The event mask for the above event handler. 00072 ACE_Reactor_Mask mask; 00073 00074 /// Flag that states whether or not the event handler is suspended. 00075 char suspended; 00076 00077 /// The number of outstanding upcalls occurring on the above event 00078 /// handler. 00079 /** 00080 * @todo The reference count should really be maintained within the 00081 * event handler. This approach was taken to allow for 00082 * backward compatibility and quick implementation. One 00083 * approach for maintaining backward compatibility while 00084 * implementing reference counting within the event handler is 00085 * to create an ACE_Ref_Counted_Event_Handler "mix-in" class 00086 * that concrete ACE_Event_Handlers can inherit from 00087 * (i.e. multiple inheritance). Thus, legacy non-reference 00088 * counted event handlers need not pay for reference counting 00089 * resources. 00090 */ 00091 unsigned long refcount; 00092 00093 }; 00094 00095 // --------------------------------------------------------------------- 00096 00097 #if 0 00098 /** 00099 * @class ACE_Dev_Poll_Ready_Set 00100 * 00101 * @brief Class that contains the list of "ready" file descriptors. 00102 * 00103 * This class points to an array of pollfd structures corresponding to 00104 * "ready" file descriptors, such as those corresponding to event 00105 * handlers that request an additional callback after being initially 00106 * dispatched (i.e. return a value greater than zero). 00107 * @par 00108 * The idea is to store the "ready" set in an existing area of memory 00109 * that already contains pollfd instances. Doing so is safe since the 00110 * "ready" set is dispatched before polling for additional events, 00111 * thus avoiding being potentially overwritten during the event poll. 00112 * @par 00113 * When the "ready" set is dispatched, all that needs to be done is to 00114 * iterate over the contents of the array. There is no need to "walk" 00115 * the array in search of ready file descriptors since the array by 00116 * design only contains ready file descriptors. As such, this 00117 * implementation of a ready set is much more efficient in the 00118 * presence of a large number of file descriptors in terms of both 00119 * time and space than the one used in the Select_Reactor, for 00120 * example. 00121 */ 00122 class ACE_Dev_Poll_Ready_Set 00123 { 00124 public: 00125 00126 /// Constructor. 00127 ACE_Dev_Poll_Ready_Set (void); 00128 00129 public: 00130 00131 /// The array containing the pollfd structures corresponding to the 00132 /// "ready" file descriptors. 00133 struct pollfd *pfds; 00134 00135 /// The number of "ready" file descriptors in the above array. 00136 int nfds; 00137 00138 }; 00139 #endif /* 0 */ 00140 00141 // --------------------------------------------------------------------- 00142 00143 /** 00144 * @class ACE_Dev_Poll_Reactor_Notify 00145 * 00146 * @brief Event handler used for unblocking the ACE_Dev_Poll_Reactor 00147 * from its event loop. 00148 * 00149 * This event handler is used internally by the ACE_Dev_Poll_Reactor 00150 * as a means to allow a thread other then the one running the event 00151 * loop to unblock the event loop. 00152 */ 00153 class ACE_Dev_Poll_Reactor_Notify : public ACE_Reactor_Notify 00154 { 00155 public: 00156 00157 /// Constructor 00158 ACE_Dev_Poll_Reactor_Notify (void); 00159 00160 /** 00161 * @name Initialization and Termination Methods 00162 * 00163 * Methods called when initializing and terminating this event 00164 * handler. 00165 */ 00166 virtual int open (ACE_Reactor_Impl *, 00167 ACE_Timer_Queue *timer_queue = 0, 00168 int disable_notify = 0); 00169 virtual int close (void); 00170 00171 /** 00172 * Called by a thread when it wants to unblock the Reactor_Impl. 00173 * This wakeups the Reactor_Impl if currently blocked. Pass over 00174 * both the Event_Handler *and* the mask to allow the caller to 00175 * dictate which Event_Handler method the Reactor_Impl will 00176 * invoke. The ACE_Time_Value indicates how long to blocking 00177 * trying to notify the Reactor_Impl. If timeout == 0, the 00178 * caller will block until action is possible, else will wait until 00179 * the relative time specified in *timeout elapses). 00180 */ 00181 virtual ssize_t notify (ACE_Event_Handler * = 0, 00182 ACE_Reactor_Mask = ACE_Event_Handler::EXCEPT_MASK, 00183 ACE_Time_Value * = 0); 00184 00185 /// Unimplemented method required by pure virtual method in abstract 00186 /// base class. 00187 /** 00188 * This method's interface is not very compatibile with this 00189 * Reactor's design. It's not clear why this method is pure virtual 00190 * either. 00191 */ 00192 virtual int dispatch_notifications (int &number_of_active_handles, 00193 ACE_Handle_Set &rd_mask); 00194 00195 /// Returns the ACE_HANDLE of the notify pipe on which the reactor 00196 /// is listening for notifications so that other threads can unblock 00197 /// the Reactor_Impl. 00198 virtual ACE_HANDLE notify_handle (void); 00199 00200 /// Verify whether the buffer has dispatchable info or not. 00201 virtual int is_dispatchable (ACE_Notification_Buffer &buffer); 00202 00203 /// Handle one of the notify call on the handle. This could be 00204 /// because of a thread trying to unblock the Reactor_Impl. 00205 virtual int dispatch_notify (ACE_Notification_Buffer &buffer); 00206 00207 /// Read one of the notify call on the handle into the 00208 /// buffer. This could be because of a thread trying to unblock 00209 /// the Reactor_Impl. 00210 virtual int read_notify_pipe (ACE_HANDLE handle, 00211 ACE_Notification_Buffer &buffer); 00212 00213 /// Called back by the ACE_Dev_Poll_Reactor when a thread wants to 00214 /// unblock us. 00215 virtual int handle_input (ACE_HANDLE handle); 00216 00217 /** 00218 * Set the maximum number of times that the handle_input method 00219 * will iterate and dispatch the ACE_Event_Handlers that are 00220 * passed in via the notify queue before breaking out of the event 00221 * loop. By default, this is set to -1, which means "iterate until 00222 * the queue is empty." Setting this to a value like "1 or 2" will 00223 * increase "fairness" (and thus prevent starvation) at the expense 00224 * of slightly higher dispatching overhead. 00225 */ 00226 virtual void max_notify_iterations (int); 00227 00228 /** 00229 * Get the maximum number of times that the handle_input method 00230 * will iterate and dispatch the ACE_Event_Handlers that are 00231 * passed in via the notify queue before breaking out of its event 00232 * loop. 00233 */ 00234 virtual int max_notify_iterations (void); 00235 00236 /** 00237 * Purge any notifications pending in this reactor for the specified 00238 * ACE_Event_Handler object. Returns the number of notifications 00239 * purged. Returns -1 on error. 00240 */ 00241 virtual int purge_pending_notifications ( 00242 ACE_Event_Handler * = 0, 00243 ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK); 00244 00245 00246 00247 /// Dump the state of an object. 00248 virtual void dump (void) const; 00249 00250 protected: 00251 00252 /** 00253 * Keep a back pointer to the ACE_Dev_Poll_Reactor. If this value 00254 * if NULL then the ACE_Dev_Poll_Reactor has been initialized with 00255 * disable_notify_pipe. 00256 */ 00257 ACE_Dev_Poll_Reactor *dp_reactor_; 00258 00259 /** 00260 * Contains the ACE_HANDLE the ACE_Dev_Poll_Reactor is listening 00261 * on, as well as the ACE_HANDLE that threads wanting the attention 00262 * of the ACE_Dev_Poll_Reactor will write to. 00263 */ 00264 ACE_Pipe notification_pipe_; 00265 00266 /** 00267 * Keeps track of the maximum number of times that the 00268 * ACE_Dev_Poll_Reactor_Notify::handle_input method will iterate and 00269 * dispatch the ACE_Event_Handlers that are passed in via the 00270 * notify pipe before breaking out of its recv loop. By default, 00271 * this is set to -1, which means "iterate until the pipe is empty." 00272 */ 00273 int max_notify_iterations_; 00274 00275 #if defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE) 00276 /** 00277 * @name Reactor Notification Attributes 00278 * 00279 * This configuration queues up notifications in separate buffers 00280 * that are in user-space, rather than stored in a pipe in the OS 00281 * kernel. The kernel-level notifications are used only to trigger 00282 * the Reactor to check its notification queue. This enables many 00283 * more notifications to be stored than would otherwise be the 00284 * case. 00285 */ 00286 //@{ 00287 00288 /// Keeps track of allocated arrays of type 00289 /// ACE_Notification_Buffer. 00290 ACE_Unbounded_Queue <ACE_Notification_Buffer *> alloc_queue_; 00291 00292 /// Keeps track of all pending notifications. 00293 ACE_Unbounded_Queue <ACE_Notification_Buffer *> notify_queue_; 00294 00295 /// Keeps track of all free buffers. 00296 ACE_Unbounded_Queue <ACE_Notification_Buffer *> free_queue_; 00297 00298 /// Synchronization for handling of queues. 00299 ACE_SYNCH_MUTEX notify_queue_lock_; 00300 00301 //@} 00302 #endif /* ACE_HAS_REACTOR_NOTIFICATION_QUEUE */ 00303 00304 }; 00305 00306 // --------------------------------------------------------------------- 00307 00308 /** 00309 * @class ACE_Dev_Poll_Reactor_Handler_Repository 00310 * 00311 * @brief Used to map ACE_HANDLEs onto the appropriate 00312 * ACE_Event_Handler *. 00313 * 00314 * This class is simply a container that maps a handle to its 00315 * corresponding event handler. It is not meant for use outside of 00316 * the Dev_Poll_Reactor. 00317 */ 00318 class ACE_Dev_Poll_Reactor_Handler_Repository 00319 { 00320 public: 00321 00322 /// Constructor. 00323 ACE_Dev_Poll_Reactor_Handler_Repository (void); 00324 00325 /// Initialize a repository of the appropriate <size>. 00326 int open (size_t size); 00327 00328 /// Close down the repository. 00329 int close (void); 00330 00331 /** 00332 * @name Repository Manipulation Operations 00333 * 00334 * Methods used to search and modify the handler repository. 00335 */ 00336 //@{ 00337 00338 /** 00339 * Return the ACE_Event_Handler associated with ACE_HANDLE. If 00340 * index_p is non-zero, then return the index location of the 00341 * handle, if found. 00342 */ 00343 ACE_Event_Handler *find (ACE_HANDLE handle, size_t *index_p = 0); 00344 00345 /// Set the event mask for event handler associated with the given 00346 /// handle. 00347 void mask (ACE_HANDLE handle, ACE_Reactor_Mask mask); 00348 00349 /// Retrieve the event mask for the event handler associated with 00350 /// the given handle. 00351 ACE_Reactor_Mask mask (ACE_HANDLE handle); 00352 00353 /// Mark the event handler associated with the given handle as 00354 /// "suspended." 00355 void suspend (ACE_HANDLE handle); 00356 00357 /// Mark the event handler associated with the given handle as 00358 /// "resumed." 00359 void resume (ACE_HANDLE handle); 00360 00361 /// Is the event handler for the given handle suspended? 00362 int suspended (ACE_HANDLE handle) const; 00363 00364 /// Bind the ACE_Event_Handler to the ACE_HANDLE with the 00365 /// appropriate ACE_Reactor_Mask settings. 00366 int bind (ACE_HANDLE handle, 00367 ACE_Event_Handler *handler, 00368 ACE_Reactor_Mask mask); 00369 00370 /// Remove the binding of ACE_HANDLE in accordance with the <mask>. 00371 int unbind (ACE_HANDLE handle); 00372 00373 /// Remove all the (ACE_HANDLE, ACE_Event_Handler) tuples. 00374 int unbind_all (void); 00375 00376 /// Increase the reference count on the event handler corresponding 00377 /// to the given file descriptor. 00378 /** 00379 * @return Returns the updated reference count. 00380 */ 00381 unsigned long add_ref (ACE_HANDLE handle); 00382 00383 /// Decrease the reference count on the event handler corresponding 00384 /// to the given file descriptor. 00385 /** 00386 * @return Returns the updated reference count. 00387 */ 00388 unsigned long remove_ref (ACE_HANDLE handle); 00389 //@} 00390 00391 /** 00392 * @name Sanity Checking 00393 * 00394 * Methods used to prevent "out-of-range" errors when indexing the 00395 * underlying handler array. 00396 */ 00397 //@{ 00398 00399 // Check the <handle> to make sure it's a valid ACE_HANDLE that 00400 // within the range of legal handles (i.e., greater than or equal to 00401 // zero and less than max_size_). 00402 int invalid_handle (ACE_HANDLE handle) const; 00403 00404 // Check the handle to make sure it's a valid ACE_HANDLE that is 00405 // within the range of currently registered handles (i.e., greater 00406 // than or equal to zero and less than max_handlep1_). 00407 int handle_in_range (ACE_HANDLE handle) const; 00408 00409 //@} 00410 00411 /// Returns the current table size. 00412 size_t size (void) const; 00413 00414 /// Dump the state of an object. 00415 void dump (void) const; 00416 00417 /// Declare the dynamic allocation hooks. 00418 ACE_ALLOC_HOOK_DECLARE; 00419 00420 private: 00421 00422 /// Maximum number of handles. 00423 int max_size_; 00424 00425 /// The underlying array of event handlers. 00426 /** 00427 * The array of event handlers is directly indexed directly using 00428 * an ACE_HANDLE value. This is Unix-specific. 00429 */ 00430 ACE_Dev_Poll_Event_Tuple *handlers_; 00431 00432 }; 00433 00434 // --------------------------------------------------------------------- 00435 00436 /** 00437 * @class ACE_Dev_Poll_Reactor 00438 * 00439 * @brief A `/dev/poll' or `/dev/epoll' based Reactor implemenatation. 00440 * 00441 * @note This reactor is EXPERIMENTAL. 00442 * 00443 * The ACE_Dev_Poll_Reactor uses the `/dev/poll' or '/dev/epoll' 00444 * character devices to demultiplex events on a given set of file 00445 * descriptors. Unlike select(), `/dev/poll' and `/dev/epoll' have no 00446 * hard-coded limit on the number of file descriptors that may be 00447 * handled at any given time. As such, the ACE_Dev_Poll_Reactor can 00448 * generally handle a much larger number of file descriptors than 00449 * select()-based reactors. Furthermore, since `/dev/poll' and 00450 * `/dev/epoll' both return a set of file descriptors that are active, 00451 * there is no need to "walk" the set of file descriptors to determine 00452 * which ones are active, such as what is done with the select() and 00453 * poll() system calls. All returned file descriptors are active. 00454 * This makes event dispatching very efficient. 00455 * 00456 * @note In general, this reactor may only be used to demultiplex 00457 * events on sockets. Demultiplexing events on pipes, for 00458 * example may not work. This is due to a limitation in the 00459 * underlying `/dev/poll' device driver. 00460 * 00461 * @note It is only possible to achieve millisecond timeout 00462 * resolutions with the ACE_Dev_Poll_Reactor. However, the 00463 * timeout resolution for timers is independent of the reactors 00464 * timeout resolution. As such, it may be possible to achieve 00465 * sub-millisecond timeout resolutions for timers but that is 00466 * entirely platform dependent. 00467 */ 00468 class ACE_Export ACE_Dev_Poll_Reactor : public ACE_Reactor_Impl 00469 { 00470 public: 00471 00472 /// Initialize ACE_Dev_Poll_Reactor with the default size. 00473 /** 00474 * The default size for the ACE_Dev_Poll_Reactor is the maximum 00475 * number of open file descriptors for the process. 00476 */ 00477 ACE_Dev_Poll_Reactor (ACE_Sig_Handler * = 0, 00478 ACE_Timer_Queue * = 0, 00479 int disable_notify_pipe = 0, 00480 ACE_Reactor_Notify *notify = 0, 00481 int mask_signals = 1); 00482 00483 /// Initialize ACE_Dev_Poll_Reactor with size "size." 00484 /** 00485 * @note On Unix platforms, the size parameter should be as large as 00486 * the maximum number of file descriptors allowed for a given 00487 * process. This is necessary since a file descriptor is used 00488 * to directly index the array of event handlers maintained by 00489 * the Reactor's handler repository. Direct indexing is used 00490 * for efficiency reasons. If the size parameter is less than 00491 * the process maximum, then the process maximum will be 00492 * decreased in order to prevent potential access violations. 00493 */ 00494 ACE_Dev_Poll_Reactor (size_t size, 00495 int restart = 0, 00496 ACE_Sig_Handler * = 0, 00497 ACE_Timer_Queue * = 0, 00498 int disable_notify_pipe = 0, 00499 ACE_Reactor_Notify *notify = 0, 00500 int mask_signals = 1); 00501 00502 /// Close down and release all resources. 00503 virtual ~ACE_Dev_Poll_Reactor (void); 00504 00505 /// Initialization. 00506 virtual int open (size_t size, 00507 int restart = 0, 00508 ACE_Sig_Handler * = 0, 00509 ACE_Timer_Queue * = 0, 00510 int disable_notify_pipe = 0, 00511 ACE_Reactor_Notify * = 0); 00512 00513 /** 00514 * Returns 0, if the size of the current message has been put in 00515 * size. Returns -1, if not. ACE_HANDLE allows the reactor to 00516 * check if the caller is valid. 00517 */ 00518 virtual int current_info (ACE_HANDLE, size_t & /* size */); 00519 00520 /// Use a user specified signal handler instead. 00521 virtual int set_sig_handler (ACE_Sig_Handler *signal_handler); 00522 00523 /// Set a user specified timer queue. 00524 /** 00525 * @note This method is deprecated. 00526 * @see timer_queue 00527 */ 00528 virtual int set_timer_queue (ACE_Timer_Queue *tq); 00529 00530 /// Set a user-specified timer queue. 00531 virtual int timer_queue (ACE_Timer_Queue *tq); 00532 00533 /// Return the current ACE_Timer_Queue. 00534 virtual ACE_Timer_Queue *timer_queue (void) const; 00535 00536 /// Close down and release all resources. 00537 virtual int close (void); 00538 00539 // = Event loop drivers. 00540 /** 00541 * Returns non-zero if there are I/O events "ready" for dispatching, 00542 * but does not actually dispatch the event handlers. By default, 00543 * don't block while checking this, i.e., "poll". 00544 * 00545 * @note It is only possible to achieve millisecond timeout 00546 * resolutions with the ACE_Dev_Poll_Reactor. 00547 */ 00548 virtual int work_pending ( 00549 const ACE_Time_Value &max_wait_time = ACE_Time_Value::zero); 00550 00551 /** 00552 * This event loop driver blocks for up to max_wait_time before 00553 * returning. It will return earlier if events occur. Note that 00554 * max_wait_time can be 0, in which case this method blocks 00555 * indefinitely until events occur. 00556 * @par 00557 * max_wait_time is decremented to reflect how much time this call 00558 * took. For instance, if a time value of 3 seconds is passed to 00559 * handle_events and an event occurs after 2 seconds, 00560 * max_wait_time will equal 1 second. This can be used if an 00561 * application wishes to handle events for some fixed amount of 00562 * time. 00563 * @par 00564 * Returns the total number of ACE_Event_Handlers that were 00565 * dispatched, 0 if the max_wait_time elapsed without dispatching 00566 * any handlers, or -1 if an error occurs. 00567 * @par 00568 * The only difference between alertable_handle_events and 00569 * handle_events is that in the alertable case, the event loop 00570 * will return when the system queues an I/O completion routine or 00571 * an Asynchronous Procedure Call. 00572 * 00573 * @note It is only possible to achieve millisecond timeout 00574 * resolutions with the ACE_Dev_Poll_Reactor. 00575 */ 00576 virtual int handle_events (ACE_Time_Value *max_wait_time = 0); 00577 virtual int alertable_handle_events (ACE_Time_Value *max_wait_time = 0); 00578 00579 /** 00580 * This method is just like the one above, except the 00581 * max_wait_time value is a reference and can therefore never be 00582 * NULL. 00583 * 00584 * @note It is only possible to achieve millisecond timeout 00585 * resolutions with the ACE_Dev_Poll_Reactor. 00586 */ 00587 virtual int handle_events (ACE_Time_Value &max_wait_time); 00588 virtual int alertable_handle_events (ACE_Time_Value &max_wait_time); 00589 00590 // = Event handling control. 00591 00592 /** 00593 * Return the status of Reactor. If this function returns 0, the 00594 * reactor is actively handling events. If it returns non-zero, 00595 * handle_events() and handle_alertable_events() return -1 00596 * immediately. 00597 */ 00598 virtual int deactivated (void); 00599 00600 /** 00601 * Control whether the Reactor will handle any more incoming events 00602 * or not. If do_stop == 1, the Reactor will be disabled. By 00603 * default, a reactor is in active state and can be 00604 * deactivated/reactived as desired. 00605 */ 00606 virtual void deactivate (int do_stop); 00607 00608 // = Register and remove Handlers. 00609 00610 /// Register event_handler with mask. The I/O handle will always 00611 /// come from get_handle on the event_handler. 00612 virtual int register_handler (ACE_Event_Handler *event_handler, 00613 ACE_Reactor_Mask mask); 00614 00615 /// Register event_handler with mask. The I/O handle is provided 00616 /// through the io_handle parameter. 00617 virtual int register_handler (ACE_HANDLE io_handle, 00618 ACE_Event_Handler *event_handler, 00619 ACE_Reactor_Mask mask); 00620 00621 /** 00622 * Register an <event_handler> that will be notified when 00623 * <event_handle> is signaled. <mask> specifies the network events 00624 * that the <event_handler> is interested in. 00625 */ 00626 virtual int register_handler (ACE_HANDLE event_handle, 00627 ACE_HANDLE io_handle, 00628 ACE_Event_Handler *event_handler, 00629 ACE_Reactor_Mask mask); 00630 00631 /// Register <event_handler> with all the <handles> in the <Handle_Set>. 00632 virtual int register_handler (const ACE_Handle_Set &handles, 00633 ACE_Event_Handler *event_handler, 00634 ACE_Reactor_Mask mask); 00635 00636 /** 00637 * Register <new_sh> to handle the signal <signum> using the 00638 * <new_disp>. Returns the <old_sh> that was previously registered 00639 * (if any), along with the <old_disp> of the signal handler. 00640 */ 00641 virtual int register_handler (int signum, 00642 ACE_Event_Handler *new_sh, 00643 ACE_Sig_Action *new_disp = 0, 00644 ACE_Event_Handler **old_sh = 0, 00645 ACE_Sig_Action *old_disp = 0); 00646 00647 /// Registers <new_sh> to handle a set of signals <sigset> using the 00648 /// <new_disp>. 00649 virtual int register_handler (const ACE_Sig_Set &sigset, 00650 ACE_Event_Handler *new_sh, 00651 ACE_Sig_Action *new_disp = 0); 00652 00653 /** 00654 * Removes <event_handler>. Note that the I/O handle will be 00655 * obtained using <get_handle> method of <event_handler> . If 00656 * <mask> == <ACE_Event_Handler::DONT_CALL> then the <handle_close> 00657 * method of the <event_handler> is not invoked. 00658 */ 00659 virtual int remove_handler (ACE_Event_Handler *event_handler, 00660 ACE_Reactor_Mask mask); 00661 00662 /** 00663 * Removes <handle>. If <mask> == <ACE_Event_Handler::DONT_CALL> 00664 * then the <handle_close> method of the associated <event_handler> 00665 * is not invoked. 00666 */ 00667 virtual int remove_handler (ACE_HANDLE handle, 00668 ACE_Reactor_Mask mask); 00669 00670 /** 00671 * Removes all handles in <handle_set>. If <mask> == 00672 * <ACE_Event_Handler::DONT_CALL> then the <handle_close> method of 00673 * the associated <event_handler>s is not invoked. 00674 */ 00675 virtual int remove_handler (const ACE_Handle_Set &handle_set, 00676 ACE_Reactor_Mask mask); 00677 00678 /** 00679 * Remove the ACE_Event_Handler currently associated with <signum>. 00680 * Install the new disposition (if given) and return the previous 00681 * disposition (if desired by the caller). Returns 0 on success and 00682 * -1 if <signum> is invalid. 00683 */ 00684 virtual int remove_handler (int signum, 00685 ACE_Sig_Action *new_disp, 00686 ACE_Sig_Action *old_disp = 0, 00687 int sigkey = -1); 00688 00689 /// Calls <remove_handler> for every signal in <sigset>. 00690 virtual int remove_handler (const ACE_Sig_Set &sigset); 00691 00692 // = Suspend and resume Handlers. 00693 00694 /// Suspend event_handler temporarily. Use 00695 /// ACE_Event_Handler::get_handle() to get the handle. 00696 virtual int suspend_handler (ACE_Event_Handler *event_handler); 00697 00698 /// Suspend handle temporarily. 00699 virtual int suspend_handler (ACE_HANDLE handle); 00700 00701 /// Suspend all handles in handle set temporarily. 00702 virtual int suspend_handler (const ACE_Handle_Set &handles); 00703 00704 /// Suspend all handles temporarily. 00705 virtual int suspend_handlers (void); 00706 00707 /// Resume event_handler. Use ACE_Event_Handler::get_handle() to 00708 /// get the handle. 00709 virtual int resume_handler (ACE_Event_Handler *event_handler); 00710 00711 /// Resume handle. 00712 virtual int resume_handler (ACE_HANDLE handle); 00713 00714 /// Resume all handles in handle set. 00715 virtual int resume_handler (const ACE_Handle_Set &handles); 00716 00717 /// Resume all handles. 00718 virtual int resume_handlers (void); 00719 00720 /// Does the reactor allow the application to resume the handle on 00721 /// its own, i.e., can it pass on the control of handle resumption to 00722 /// the application. 00723 virtual int resumable_handler (void); 00724 00725 /// Return 1 if we any event associations were made by the reactor 00726 /// for the handles that it waits on, 0 otherwise. 00727 virtual int uses_event_associations (void); 00728 00729 // = Timer management. 00730 00731 /** 00732 * Schedule an ACE_Event_Handler that will expire after an amount 00733 * of time. The return value of this method, a timer_id value, 00734 * uniquely identifies the event_handler in the ACE_Reactor's 00735 * internal list of timers. 00736 * This timer_id value can be used to cancel the timer 00737 * with the cancel_timer() call. 00738 * 00739 * @see cancel_timer() 00740 * @see reset_timer_interval() 00741 * 00742 * @param event_handler event handler to schedule on reactor 00743 * @param arg argument passed to the handle_timeout() method of event_handler 00744 * @param delay time interval after which the timer will expire 00745 * @param interval time interval after which the timer will be automatically rescheduled 00746 * @return -1 on failure, a timer_id value on success 00747 */ 00748 virtual long schedule_timer (ACE_Event_Handler *event_handler, 00749 const void *arg, 00750 const ACE_Time_Value &delay, 00751 const ACE_Time_Value &interval = ACE_Time_Value::zero); 00752 00753 /** 00754 * Resets the interval of the timer represented by <timer_id> to 00755 * <interval>, which is specified in relative time to the current 00756 * <gettimeofday>. If <interval> is equal to 00757 * <ACE_Time_Value::zero>, the timer will become a non-rescheduling 00758 * timer. Returns 0 if successful, -1 if not. 00759 */ 00760 virtual int reset_timer_interval (long timer_id, 00761 const ACE_Time_Value &interval); 00762 00763 /// Cancel all Event_Handlers that match the address of 00764 /// <event_handler>. Returns number of handlers cancelled. 00765 virtual int cancel_timer (ACE_Event_Handler *event_handler, 00766 int dont_call_handle_close = 1); 00767 00768 /** 00769 * Cancel the single Event_Handler that matches the <timer_id> value 00770 * (which was returned from the schedule method). If arg is 00771 * non-NULL then it will be set to point to the ``magic cookie'' 00772 * argument passed in when the Event_Handler was registered. This 00773 * makes it possible to free up the memory and avoid memory leaks. 00774 * Returns 1 if cancellation succeeded and 0 if the <timer_id> 00775 * wasn't found. 00776 */ 00777 virtual int cancel_timer (long timer_id, 00778 const void **arg = 0, 00779 int dont_call_handle_close = 1); 00780 00781 // = High-level Event_Handler scheduling operations 00782 00783 /// Add <masks_to_be_added> to the <event_handler>'s entry. 00784 /// <event_handler> must already have been registered. 00785 virtual int schedule_wakeup (ACE_Event_Handler *event_handler, 00786 ACE_Reactor_Mask masks_to_be_added); 00787 00788 /// Add <masks_to_be_added> to the <handle>'s entry. <event_handler> 00789 /// associated with <handle> must already have been registered. 00790 virtual int schedule_wakeup (ACE_HANDLE handle, 00791 ACE_Reactor_Mask masks_to_be_added); 00792 00793 /// Clear <masks_to_be_cleared> from the <event_handler>'s entry. 00794 virtual int cancel_wakeup (ACE_Event_Handler *event_handler, 00795 ACE_Reactor_Mask masks_to_be_cleared); 00796 00797 /// Clear <masks_to_be_cleared> from the <handle>'s entry. 00798 virtual int cancel_wakeup (ACE_HANDLE handle, 00799 ACE_Reactor_Mask masks_to_be_cleared); 00800 00801 // = Notification methods. 00802 00803 /** 00804 * Notify <event_handler> of <mask> event. The <ACE_Time_Value> 00805 * indicates how long to blocking trying to notify. If <timeout> == 00806 * 0, the caller will block until action is possible, else will wait 00807 * until the relative time specified in <timeout> elapses). 00808 */ 00809 virtual int notify (ACE_Event_Handler *event_handler = 0, 00810 ACE_Reactor_Mask mask = ACE_Event_Handler::EXCEPT_MASK, 00811 ACE_Time_Value * = 0); 00812 00813 /** 00814 * Set the maximum number of times that ACE_Reactor_Impl will 00815 * iterate and dispatch the <ACE_Event_Handlers> that are passed in 00816 * via the notify queue before breaking out of its 00817 * <ACE_Message_Queue::dequeue> loop. By default, this is set to 00818 * -1, which means "iterate until the queue is empty." Setting this 00819 * to a value like "1 or 2" will increase "fairness" (and thus 00820 * prevent starvation) at the expense of slightly higher dispatching 00821 * overhead. 00822 */ 00823 virtual void max_notify_iterations (int); 00824 00825 /** 00826 * Get the maximum number of times that the ACE_Reactor_Impl will 00827 * iterate and dispatch the <ACE_Event_Handlers> that are passed in 00828 * via the notify queue before breaking out of its 00829 * <ACE_Message_Queue::dequeue> loop. 00830 */ 00831 virtual int max_notify_iterations (void); 00832 00833 /** 00834 * Purge any notifications pending in this reactor for the specified 00835 * <ACE_Event_Handler> object. Returns the number of notifications 00836 * purged. Returns -1 on error. 00837 */ 00838 virtual int purge_pending_notifications (ACE_Event_Handler * = 0, 00839 ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK); 00840 00841 /** 00842 * Check to see if <handle> is associated with a valid Event_Handler 00843 * bound to <mask>. Return the <event_handler> associated with this 00844 * <handler> if <event_handler> != 0. 00845 */ 00846 virtual int handler (ACE_HANDLE handle, 00847 ACE_Reactor_Mask mask, 00848 ACE_Event_Handler **event_handler = 0); 00849 00850 /** 00851 * Check to see if <signum> is associated with a valid Event_Handler 00852 * bound to a signal. Return the <event_handler> associated with 00853 * this <handler> if <event_handler> != 0. 00854 */ 00855 virtual int handler (int signum, 00856 ACE_Event_Handler ** = 0); 00857 00858 /// Returns true if Reactor has been successfully initialized, else 00859 /// false. 00860 virtual int initialized (void); 00861 00862 /// Returns the current size of the Reactor's internal descriptor 00863 /// table. 00864 virtual size_t size (void) const; 00865 00866 /// Returns a reference to the Reactor's internal lock. 00867 virtual ACE_Lock &lock (void); 00868 00869 /// Wake up all threads waiting in the event loop. 00870 virtual void wakeup_all_threads (void); 00871 00872 /// Transfers ownership of Reactor_Impl to the new_owner. 00873 /** 00874 * @note There is no need to set the owner of the event loop for the 00875 * ACE_Dev_Poll_Reactor. Multiple threads may invoke the 00876 * event loop simulataneously. As such, this method is a 00877 * no-op. 00878 */ 00879 virtual int owner (ACE_thread_t new_owner, ACE_thread_t *old_owner = 0); 00880 00881 /// Return the ID of the "owner" thread. 00882 /** 00883 * @note There is no need to set the owner of the event loop for the 00884 * ACE_Dev_Poll_Reactor. Multiple threads may invoke the 00885 * event loop simulataneously. As such, this method is a 00886 * no-op. 00887 */ 00888 virtual int owner (ACE_thread_t *owner); 00889 00890 /// Get the existing restart value. 00891 virtual int restart (void); 00892 00893 /// Set a new value for restart and return the original value. 00894 /** 00895 * @param r If zero, then the event loop will not be automatically 00896 * restarted if the underlying poll is interrupted via the 00897 * INTR (interrupt) signal. 00898 * 00899 * @return Returns the previous "restart" value. 00900 */ 00901 virtual int restart (int r); 00902 00903 /// Set position of the owner thread. 00904 /** 00905 * @note This is currently a no-op. 00906 */ 00907 virtual void requeue_position (int); 00908 00909 /// Get position of the owner thread. 00910 /** 00911 * @note This is currently a no-op. 00912 */ 00913 virtual int requeue_position (void); 00914 00915 /** 00916 * @name Low-level wait_set mask manipulation methods 00917 * 00918 * Low-level methods to manipulate the event/reactor mask associated 00919 * with a handle and event handler when polling for events. 00920 * @par 00921 * The "interest set," i.e. the wait set, can be directly 00922 * manipulated with these methods. 00923 */ 00924 //@{ 00925 00926 /// GET/SET/ADD/CLR the dispatch mask "bit" bound with the 00927 /// event_handler and mask. 00928 virtual int mask_ops (ACE_Event_Handler *event_handler, 00929 ACE_Reactor_Mask mask, 00930 int ops); 00931 00932 /// GET/SET/ADD/CLR the dispatch MASK "bit" bound with the handle 00933 /// and mask. 00934 virtual int mask_ops (ACE_HANDLE handle, 00935 ACE_Reactor_Mask mask, 00936 int ops); 00937 00938 //@} 00939 00940 /** 00941 * @name Low-level ready_set mask manipulation methods 00942 * 00943 * These methods are unimplemented. 00944 */ 00945 //@{ 00946 00947 /// GET/SET/ADD/CLR the ready "bit" bound with the event_handler 00948 /// and mask. 00949 virtual int ready_ops (ACE_Event_Handler *event_handler, 00950 ACE_Reactor_Mask mask, 00951 int ops); 00952 00953 /// GET/SET/ADD/CLR the ready "bit" bound with the handle and mask. 00954 virtual int ready_ops (ACE_HANDLE handle, 00955 ACE_Reactor_Mask, 00956 int ops); 00957 00958 //@} 00959 00960 /// Dump the state of an object. 00961 virtual void dump (void) const; 00962 00963 /// Declare the dynamic allocation hooks. 00964 ACE_ALLOC_HOOK_DECLARE; 00965 00966 protected: 00967 00968 /// Non-locking version of wait_pending(). 00969 /** 00970 * Returns non-zero if there are I/O events "ready" for dispatching, 00971 * but does not actually dispatch the event handlers. By default, 00972 * don't block while checking this, i.e., "poll". 00973 * 00974 * @note It is only possible to achieve millisecond timeout 00975 * resolutions with the ACE_Dev_Poll_Reactor. 00976 */ 00977 int work_pending_i (ACE_Time_Value *max_wait_time); 00978 00979 /// Poll for events and return the number of event handlers that 00980 /// were dispatched. 00981 /** 00982 * This is a helper method called by all handle_events() methods. 00983 */ 00984 int handle_events_i (ACE_Time_Value *max_wait_time); 00985 00986 /// Perform the upcall with the given event handler method. 00987 int upcall (ACE_Event_Handler *event_handler, 00988 int (ACE_Event_Handler::*callback)(ACE_HANDLE), 00989 ACE_HANDLE handle); 00990 00991 /** 00992 * Dispatch ACE_Event_Handlers for time events, I/O events, and 00993 * signal events. Returns the total number of ACE_Event_Handlers 00994 * that were dispatched or -1 if something goes wrong. 00995 */ 00996 int dispatch (void); 00997 00998 /// 00999 int dispatch_timer_handlers (int &number_of_handlers_dispatched); 01000 01001 /// Dispatch all IO related events to their corresponding event 01002 /// handlers. 01003 int dispatch_io_events (int &io_handlers_dispatched); 01004 01005 /// Register the given event handler with the reactor. 01006 int register_handler_i (ACE_HANDLE handle, 01007 ACE_Event_Handler *eh, 01008 ACE_Reactor_Mask mask); 01009 01010 /// Remove the event handler associated with the given handle and 01011 /// event mask from the "interest set." 01012 int remove_handler_i (ACE_HANDLE handle, ACE_Reactor_Mask mask); 01013 01014 /// Temporarily remove the given handle from the "interest set." 01015 int suspend_handler_i (ACE_HANDLE handle); 01016 01017 /// Place the given handle that was temporarily removed from the 01018 /// "interest set," i.e that was suspended, back in to the interest 01019 /// set. The given handle will once again be polled for events. 01020 int resume_handler_i (ACE_HANDLE handle); 01021 01022 /// GET/SET/ADD/CLR the dispatch MASK "bit" bound with the handle 01023 /// and mask. This internal helper method acquires no lock. 01024 int mask_ops_i (ACE_HANDLE handle, 01025 ACE_Reactor_Mask mask, 01026 int ops); 01027 01028 /// Convert a reactor mask to its corresponding poll() event mask. 01029 short reactor_mask_to_poll_event (ACE_Reactor_Mask mask); 01030 01031 protected: 01032 01033 /// Has the reactor been initialized. 01034 char initialized_; 01035 01036 /// The file descriptor associated with the open `/dev/poll' or 01037 /// `/dev/epoll' device. 01038 /** 01039 * All interactions with the `/dev/poll' or `/dev/epoll' device are 01040 * done through this file descriptor. 01041 */ 01042 ACE_HANDLE poll_fd_; 01043 01044 /// The maximum number of file descriptors over which demultiplexing 01045 /// will occur. 01046 size_t size_; 01047 01048 /// Track HANDLES we are interested in for various events that must 01049 /// be dispatched *without* polling. 01050 /// ACE_Dev_Poll_Ready_Set ready_set_; 01051 01052 #if defined (ACE_HAS_EVENT_POLL) 01053 /// The memory map that `/dev/epoll' will feed its results to. 01054 char *mmap_; 01055 #else 01056 /// The pollfd array that `/dev/poll' will feed its results to. 01057 struct pollfd *dp_fds_; 01058 #endif /* ACE_HAS_EVENT_POLL */ 01059 01060 /// Pointer to the next pollfd array element that contains the next 01061 /// event to be dispatched. 01062 struct pollfd *start_pfds_; 01063 01064 /// The last element in the pollfd array plus one. 01065 /** 01066 * The loop that dispatches IO events stops when this->start_pfds == 01067 * this->end_pfds_. 01068 */ 01069 struct pollfd *end_pfds_; 01070 01071 /// This flag is used to keep track of whether we are actively handling 01072 /// events or not. 01073 sig_atomic_t deactivated_; 01074 01075 /// Lock used for synchronization of reactor state. 01076 ACE_SYNCH_MUTEX lock_; 01077 01078 /// Adapter used to return internal lock to outside world. 01079 ACE_Lock_Adapter<ACE_SYNCH_MUTEX> lock_adapter_; 01080 01081 /// The repository that contains all registered event handlers. 01082 ACE_Dev_Poll_Reactor_Handler_Repository handler_rep_; 01083 01084 /// Defined as a pointer to allow overriding by derived classes... 01085 ACE_Timer_Queue *timer_queue_; 01086 01087 /// Keeps track of whether we should delete the timer queue (if we 01088 /// didn't create it, then we don't delete it). 01089 int delete_timer_queue_; 01090 01091 /// Handle signals without requiring global/static variables. 01092 ACE_Sig_Handler *signal_handler_; 01093 01094 /// Keeps track of whether we should delete the signal handler (if we 01095 /// didn't create it, then we don't delete it). 01096 int delete_signal_handler_; 01097 01098 /// Callback object that unblocks the <ACE_Select_Reactor> if it's 01099 /// sleeping. 01100 ACE_Reactor_Notify *notify_handler_; 01101 01102 /// Keeps track of whether we need to delete the notify handler (if 01103 /// we didn't create it, then we don't delete it). 01104 int delete_notify_handler_; 01105 01106 /// Flag that determines if signals are masked during event 01107 /// dispatching. 01108 /** 01109 * If 0 then the Reactor will not mask the signals during the event 01110 * dispatching. This is useful for applications that do not 01111 * register any signal handlers and want to reduce the overhead 01112 * introduce by the kernel level locks required to change the mask. 01113 */ 01114 int mask_signals_; 01115 01116 /// Restart the handle_events event loop method automatically when 01117 /// polling function in use (ioctl() in this case) is interrupted 01118 /// via an EINTR signal. 01119 int restart_; 01120 01121 }; 01122 01123 01124 /** 01125 * @class ACE_Dev_Poll_Handler_Guard 01126 * 01127 * @brief Class used to make event handler reference count 01128 * manipulation exception-safe. 01129 * 01130 * This class makes the reference count manipulation that occurs 01131 * during an upcall exception-safe. Prior to dispatching the event 01132 * handler, the reference count is increased. Once the upcall for the 01133 * given event handler is complete, its reference count will be decreased. 01134 */ 01135 class ACE_Dev_Poll_Handler_Guard 01136 { 01137 public: 01138 01139 /// Constructor 01140 /** 01141 * The constructor increments the reference count on the event 01142 * handler corresponding to the given handle. 01143 */ 01144 ACE_Dev_Poll_Handler_Guard ( 01145 ACE_Dev_Poll_Reactor_Handler_Repository &repository, 01146 ACE_HANDLE handle); 01147 01148 /// Destructor 01149 /** 01150 * The destructor decrements the reference count on the event 01151 * handler corresponding to the given handle. 01152 */ 01153 ~ACE_Dev_Poll_Handler_Guard (void); 01154 01155 private: 01156 01157 /// Reference to the handler repository containing the event handler 01158 /// used during the upcall. 01159 ACE_Dev_Poll_Reactor_Handler_Repository &repository_; 01160 01161 /// Handle corresponding to the event being dispatched. 01162 ACE_HANDLE handle_; 01163 01164 }; 01165 01166 01167 #if defined (__ACE_INLINE__) 01168 # include "ace/Dev_Poll_Reactor.inl" 01169 #endif /* __ACE_INLINE__ */ 01170 01171 #endif /* ACE_HAS_EVENT_POLL || ACE_HAS_DEV_POLL */ 01172 01173 #include "ace/post.h" 01174 01175 #endif /* ACE_DEV_POLL_REACTOR_H */
1.2.14 written by Dimitri van Heesch,
© 1997-2002