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