Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

Dev_Poll_Reactor.h

Go to the documentation of this file.
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 */

Generated on Mon Jun 16 11:19:36 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002