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