WFMO_Reactor.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 //=============================================================================
00004 /**
00005  *  @file    WFMO_Reactor.h
00006  *
00007  *  $Id: WFMO_Reactor.h 81138 2008-03-28 09:18:15Z johnnyw $
00008  *
00009  *  @author Irfan Pyarali <irfan@cs.wustl.edu>
00010  *  @author Tim Harrison <harrison@cs.wustl.edu>
00011  *  @author Doug Schmidt <schmidt@cs.wustl.edu>
00012  */
00013 //=============================================================================
00014 
00015 #ifndef ACE_WFMO_REACTOR_H
00016 #define ACE_WFMO_REACTOR_H
00017 #include /**/ "ace/pre.h"
00018 
00019 #include /**/ "ace/config-all.h"
00020 
00021 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00022 # pragma once
00023 #endif /* ACE_LACKS_PRAGMA_ONCE */
00024 
00025 #if defined (ACE_WIN32)
00026 
00027 #include "ace/Signal.h"
00028 #include "ace/Timer_Queue.h"
00029 #include "ace/Event_Handler.h"
00030 #include "ace/Auto_Event.h"
00031 #include "ace/Manual_Event.h"
00032 #include "ace/Condition_Thread_Mutex.h"
00033 #include "ace/Lock_Adapter_T.h"
00034 #include "ace/Reactor_Impl.h"
00035 #include "ace/Message_Queue.h"
00036 #include "ace/Process_Mutex.h"
00037 
00038 // If we don't have WinSOCK2, we need these defined
00039 #if !defined (ACE_HAS_WINSOCK2) || (ACE_HAS_WINSOCK2 == 0)
00040 /*
00041  * WinSock 2 extension -- bit values and indices for FD_XXX network events
00042  */
00043 #define FD_READ_BIT      0
00044 #define FD_WRITE_BIT     1
00045 #define FD_OOB_BIT       2
00046 #define FD_ACCEPT_BIT    3
00047 #define FD_CONNECT_BIT   4
00048 #define FD_CLOSE_BIT     5
00049 #define FD_QOS_BIT       6
00050 #define FD_GROUP_QOS_BIT 7
00051 
00052 #define FD_QOS           (1 << FD_QOS_BIT)
00053 #define FD_GROUP_QOS     (1 << FD_GROUP_QOS_BIT)
00054 
00055 #define FD_MAX_EVENTS    8
00056 #define FD_ALL_EVENTS    ((1 << FD_MAX_EVENTS) - 1)
00057 
00058 #define WSAEVENT                HANDLE
00059 
00060 typedef struct _WSANETWORKEVENTS
00061 {
00062   long lNetworkEvents;
00063   int iErrorCode[FD_MAX_EVENTS];
00064 } WSANETWORKEVENTS, FAR * LPWSANETWORKEVENTS;
00065 
00066 int WSAEventSelect (SOCKET s,
00067                     WSAEVENT hEventObject,
00068                     long lNetworkEvents);
00069 
00070 int WSAEnumNetworkEvents (SOCKET s,
00071                           WSAEVENT hEventObject,
00072                           LPWSANETWORKEVENTS lpNetworkEvents);
00073 
00074 #endif /* !defined ACE_HAS_WINSOCK2 */
00075 
00076 class ACE_WFMO_Reactor_Test;  // Must be out of versioned namespace.
00077 
00078 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00079 
00080 // Forward decl.
00081 class ACE_WFMO_Reactor;
00082 class ACE_Handle_Set;
00083 
00084 /**
00085  * @class ACE_Wakeup_All_Threads_Handler
00086  *
00087  * @brief This is a helper class whose sole purpose is to handle events
00088  * on <ACE_WFMO_Reactor->wakeup_all_threads_>
00089  */
00090 class ACE_Export ACE_Wakeup_All_Threads_Handler : public ACE_Event_Handler
00091 {
00092 public:
00093   /// Called when the <ACE_WFMO_Reactor->wakeup_all_threads_>
00094   virtual int handle_signal (int signum, siginfo_t * = 0, ucontext_t * = 0);
00095 };
00096 
00097 /**
00098  * @class ACE_WFMO_Reactor_Handler_Repository
00099  *
00100  * @internal This class is for internal ACE use only.
00101  *
00102  * @brief Used to map ACE_HANDLEs onto the appropriate
00103  * ACE_Event_Handler * and other information.
00104  */
00105 class ACE_Export ACE_WFMO_Reactor_Handler_Repository
00106 {
00107 public:
00108   friend class ACE_WFMO_Reactor;
00109   friend class ACE_WFMO_Reactor_Test;
00110 
00111   /**
00112    * @class Common_Info
00113    *
00114    * @brief This struct contains the necessary information for every
00115    * <Event_Handler> entry. The reason the event is not in this
00116    * structure is because we need to pass an event array into
00117    * WaitForMultipleObjects and therefore keeping the events
00118    * seperate makes sense.
00119    */
00120   class Common_Info
00121   {
00122   public:
00123     /// This indicates whether this entry is for I/O or for a regular
00124     /// event
00125     bool io_entry_;
00126 
00127     /// The assosiated <Event_Handler>
00128     ACE_Event_Handler *event_handler_;
00129 
00130     /// The I/O handle related to the <Event_Handler>.  This entry is
00131     /// only valid if the <io_entry_> flag is true.
00132     ACE_HANDLE io_handle_;
00133 
00134     /**
00135      * This is the set of events that the <Event_Handler> is
00136      * interested in. This entry is only valid if the <io_entry_> flag
00137      * is true.
00138      */
00139     long network_events_;
00140 
00141     /**
00142      * This flag indicates that <WFMO_Reactor> created the event on
00143      * behalf of the user. Therefore we need to clean this up when the
00144      * <Event_Handler> removes itself from <WFMO_Reactor>.  This entry
00145      * is only valid if the <io_entry_> flag is true.
00146      */
00147     bool delete_event_;
00148 
00149     /// This is set when the entry needed to be deleted.
00150     bool delete_entry_;
00151 
00152     /**
00153      * These are the masks related to <handle_close> for the
00154      * <Event_Handler>.  This is only valid when <delete_entry_> is
00155      * set.
00156      */
00157     ACE_Reactor_Mask close_masks_;
00158 
00159     /// Constructor used for initializing the structure
00160     Common_Info (void);
00161 
00162     /// Reset the state of the structure
00163     void reset (void);
00164 
00165     /// Set the structure to these new values
00166     void set (bool io_entry,
00167               ACE_Event_Handler *event_handler,
00168               ACE_HANDLE io_handle,
00169               long network_events,
00170               bool delete_event,
00171               bool delete_entry,
00172               ACE_Reactor_Mask close_masks);
00173 
00174     /// Set the structure to these new values
00175     void set (Common_Info &common_info);
00176 
00177     /// Dump the state of an object.
00178     void dump (void) const;
00179   };
00180 
00181   /**
00182    * @class Current_Info
00183    *
00184    * @brief This structure inherits from the common structure to add
00185    * information for current entries.
00186    */
00187   class Current_Info : public Common_Info
00188   {
00189   public:
00190     /// This is set when the entry needed to be suspended.
00191     bool suspend_entry_;
00192 
00193     /// Default constructor
00194     Current_Info (void);
00195 
00196     /// Reset the state of the structure
00197     void reset (void);
00198 
00199     /// Set the structure to these new values
00200     void set (bool io_entry,
00201               ACE_Event_Handler *event_handler,
00202               ACE_HANDLE io_handle,
00203               long network_events,
00204               bool delete_event,
00205               bool delete_entry = false,
00206               ACE_Reactor_Mask close_masks = ACE_Event_Handler::NULL_MASK,
00207               bool suspend_entry = false);
00208 
00209     /// Set the structure to these new values
00210     void set (Common_Info &common_info,
00211               bool suspend_entry = false);
00212 
00213     /// Dump the state of an object.
00214     void dump (ACE_HANDLE event_handle) const;
00215   };
00216 
00217   /**
00218    * @class To_Be_Added_Info
00219    *
00220    * @brief This structure inherits from the common structure to add
00221    * information for <to_be_added> entries.
00222    */
00223   class To_Be_Added_Info : public Common_Info
00224   {
00225   public:
00226     /// Handle for the event
00227     ACE_HANDLE event_handle_;
00228 
00229     /// This is set when the entry needed to be suspended.
00230     bool suspend_entry_;
00231 
00232     /// Default constructor
00233     To_Be_Added_Info (void);
00234 
00235     /// Reset the state of the structure
00236     void reset (void);
00237 
00238     /// Set the structure to these new values
00239     void set (ACE_HANDLE event_handle,
00240               bool io_entry,
00241               ACE_Event_Handler *event_handler,
00242               ACE_HANDLE io_handle,
00243               long network_events,
00244               bool delete_event,
00245               bool delete_entry = false,
00246               ACE_Reactor_Mask close_masks = ACE_Event_Handler::NULL_MASK,
00247               bool suspend_entry = false);
00248 
00249     /// Set the structure to these new values
00250     void set (ACE_HANDLE event_handle,
00251               Common_Info &common_info,
00252               bool suspend_entry = false);
00253 
00254     /// Dump the state of an object.
00255     void dump (void) const;
00256   };
00257 
00258   /**
00259    * @class Suspended_Info
00260    *
00261    * @brief This structure inherits from the common structure to add
00262    * information for suspended entries.
00263    */
00264   class Suspended_Info : public Common_Info
00265   {
00266   public:
00267     /// Handle for the event
00268     ACE_HANDLE event_handle_;
00269 
00270     /// This is set when the entry needed to be resumed.
00271     bool resume_entry_;
00272 
00273     /// Constructor used for initializing the structure
00274     Suspended_Info (void);
00275 
00276     /// Reset the state of the structure
00277     void reset (void);
00278 
00279     /// Set the structure to these new values
00280     void set (ACE_HANDLE event_handle,
00281               bool io_entry,
00282               ACE_Event_Handler *event_handler,
00283               ACE_HANDLE io_handle,
00284               long network_events,
00285               bool delete_event,
00286               bool delete_entry = false,
00287               ACE_Reactor_Mask close_masks = 0,
00288               bool resume_entry = false);
00289 
00290     /// Set the structure to these new values
00291     void set (ACE_HANDLE event_handle,
00292               Common_Info &common_info,
00293               bool resume_entry = false);
00294 
00295     /// Dump the state of an object.
00296     void dump (void) const;
00297   };
00298 
00299   /// Constructor.
00300   ACE_WFMO_Reactor_Handler_Repository (ACE_WFMO_Reactor &wfmo_reactor);
00301 
00302   /// Destructor.
00303   virtual ~ACE_WFMO_Reactor_Handler_Repository (void);
00304 
00305   /// Initialize the repository of the approriate @a size.
00306   int open (size_t size);
00307 
00308   /// Close down the handler repository.
00309   int close (void);
00310 
00311   // = Search structure operations.
00312 
00313   /// Bind the <ACE_Event_Handler *> to the ACE_HANDLE. This is for
00314   /// the simple event entry.
00315   int bind (ACE_HANDLE, ACE_Event_Handler *);
00316 
00317   /// Insert I/O <Event_Handler> entry into the system. This method
00318   /// assumes that the lock are head *before* this method is invoked.
00319   int bind_i (bool io_entry,
00320               ACE_Event_Handler *event_handler,
00321               long network_events,
00322               ACE_HANDLE io_handle,
00323               ACE_HANDLE event_handle,
00324               bool delete_event);
00325 
00326   /// Remove the binding of ACE_HANDLE in accordance with the @a mask.
00327   int unbind (ACE_HANDLE,
00328               ACE_Reactor_Mask mask);
00329 
00330   /// Non-lock-grabbing version of <unbind>
00331   int unbind_i (ACE_HANDLE,
00332                 ACE_Reactor_Mask mask,
00333                 bool &changes_required);
00334 
00335   /// Remove all bindings of <ACE_HANDLE, ACE_Event_Handler> tuples.
00336   void unbind_all (void);
00337 
00338   // = Sanity checking.
00339 
00340   // Check the <handle> to make sure it's a valid ACE_HANDLE
00341   int invalid_handle (ACE_HANDLE handle) const;
00342 
00343   // = Accessors.
00344   /// Maximum ACE_HANDLE value, plus 1.
00345   DWORD max_handlep1 (void) const;
00346 
00347   /// Pointer to the beginning of the current array of ACE_HANDLE
00348   /// *'s.
00349   ACE_HANDLE *handles (void) const;
00350 
00351   /// Pointer to the beginning of the current array of
00352   /// ACE_Event_Handler *'s.
00353   Current_Info *current_info (void) const;
00354 
00355   /// Check if changes to the handle set are required.
00356   virtual bool changes_required (void);
00357 
00358   /// Make changes to the handle set
00359   virtual int make_changes (void);
00360 
00361   /// Check to see if @a slot has been scheduled for deletion
00362   int scheduled_for_deletion (size_t slot) const;
00363 
00364   /**
00365    * This method is used to calculate the network mask after a mask_op
00366    * request to <WFMO_Reactor>. Note that because the <Event_Handler>
00367    * may already be in the handler repository, we may have to find the
00368    * old event and the old network events
00369    */
00370   int modify_network_events_i (ACE_HANDLE io_handle,
00371                                ACE_Reactor_Mask new_masks,
00372                                ACE_Reactor_Mask &old_masks,
00373                                long &new_network_events,
00374                                ACE_HANDLE &event_handle,
00375                                bool &delete_event,
00376                                int operation);
00377 
00378   /// This method is used to change the network mask left (if any)
00379   /// after a remove request to <WFMO_Reactor>
00380   ACE_Reactor_Mask bit_ops (long &existing_masks,
00381                             ACE_Reactor_Mask to_be_removed_masks,
00382                             int operation);
00383 
00384   /// Temporarily suspend entry
00385   int suspend_handler_i (ACE_HANDLE handle,
00386                          bool &changes_required);
00387 
00388   /// Resume suspended entry
00389   int resume_handler_i (ACE_HANDLE handle,
00390                         bool &changes_required);
00391 
00392   /// Deletions and suspensions in current_info_
00393   int make_changes_in_current_infos (void);
00394 
00395   /// Deletions and resumptions in current_suspended_info_
00396   int make_changes_in_suspension_infos (void);
00397 
00398   /// Deletions in to_be_added_info_, or transfers to current_info_ or
00399   /// current_suspended_info_ from to_be_added_info_
00400   int make_changes_in_to_be_added_infos (void);
00401 
00402   /// Removes the ACE_Event_Handler at @a slot from the table.
00403   int remove_handler_i (size_t slot,
00404                         ACE_Reactor_Mask mask);
00405 
00406   /// Removes the ACE_Event_Handler at @a slot from the table.
00407   int remove_suspended_handler_i (size_t slot,
00408                                   ACE_Reactor_Mask mask);
00409 
00410   /// Removes the ACE_Event_Handler at @a slot from the table.
00411   int remove_to_be_added_handler_i (size_t slot,
00412                                     ACE_Reactor_Mask to_be_removed_masks);
00413 
00414   /**
00415    * Return the Event_Handler associated with <handle>.  Return 0 if
00416    * <handle> is not registered.
00417    */
00418   ACE_Event_Handler *find_handler (ACE_HANDLE handle);
00419 
00420   /**
00421    * Check to see if <handle> is associated with a valid Event_Handler
00422    * bound to @a mask.  Return the <event_handler> associated with this
00423    * @a handler if <event_handler> != 0.
00424    */
00425   int handler (ACE_HANDLE handle,
00426                ACE_Reactor_Mask mask,
00427                ACE_Event_Handler **event_handler = 0);
00428 
00429   /**
00430    * Check to see if <handle> is associated with a valid
00431    * Event_Handler. Return Event_Handler and associated masks.
00432    */
00433   ACE_Event_Handler *handler (ACE_HANDLE handle,
00434                               long &existing_masks);
00435 
00436   /// Dump the state of an object.
00437   void dump (void) const;
00438 
00439 protected:
00440   /// Reference to our <WFMO_Reactor>.
00441   ACE_WFMO_Reactor &wfmo_reactor_;
00442 
00443   /// Maximum number of handles.
00444   size_t max_size_;
00445 
00446   /**
00447    * Array of <ACE_HANDLEs> passed to <WaitForMultipleObjects>.  This
00448    * is not part of the structure as the handle array needs to be
00449    * passed directly to <WaitForMultipleObjects>.
00450    */
00451   ACE_HANDLE *current_handles_;
00452 
00453   /// Array of current entries in the table
00454   Current_Info *current_info_;
00455 
00456   /// A count of the number of active handles.
00457   DWORD max_handlep1_;
00458 
00459   /// Information for entries to be added
00460   To_Be_Added_Info *to_be_added_info_;
00461 
00462   /// Number of records to be added
00463   size_t handles_to_be_added_;
00464 
00465   /// Currently suspended handles
00466   Suspended_Info *current_suspended_info_;
00467 
00468   /// Number of currently suspended handles
00469   size_t suspended_handles_;
00470 
00471   /// Number of records to be suspended
00472   size_t handles_to_be_suspended_;
00473 
00474   /// Number of records to be resumed
00475   size_t handles_to_be_resumed_;
00476 
00477   /// Number of records to be deleted
00478   size_t handles_to_be_deleted_;
00479 
00480 };
00481 
00482 /**
00483  * @class ACE_WFMO_Reactor_Notify
00484  *
00485  * @brief Unblock the <ACE_WFMO_Reactor> from its event loop, passing
00486  * it an optional ACE_Event_Handler to dispatch.
00487  *
00488  * This implementation is necessary for cases where the
00489  * <ACE_WFMO_Reactor> is run in a multi-threaded program.  In
00490  * this case, we need to be able to unblock
00491  * <WaitForMultipleObjects> when updates occur other than in the
00492  * main <ACE_WFMO_Reactor> thread.  To do this, we signal an
00493  * auto-reset event the <ACE_WFMO_Reactor> is listening on.  If
00494  * an ACE_Event_Handler and ACE_Reactor_Mask is passed to
00495  * <notify>, the appropriate <handle_*> method is dispatched.
00496  */
00497 class ACE_Export ACE_WFMO_Reactor_Notify : public ACE_Reactor_Notify
00498 {
00499 public:
00500   /// Constructor
00501   ACE_WFMO_Reactor_Notify (size_t max_notifies = 1024);
00502 
00503   /// Initialization. <timer_queue> is stored to call <gettimeofday>.
00504   virtual int open (ACE_Reactor_Impl *wfmo_reactor,
00505                     ACE_Timer_Queue *timer_queue,
00506                     int disable_notify = 0);
00507 
00508   /// No-op.
00509   virtual int close (void);
00510 
00511   /**
00512    * Special trick to unblock <WaitForMultipleObjects> when updates
00513    * occur.  All we do is enqueue <event_handler> and @a mask onto the
00514    * ACE_Message_Queue and wakeup the <WFMO_Reactor> by signaling
00515    * its <ACE_Event> handle.  The ACE_Time_Value indicates how long
00516    * to blocking trying to notify the <WFMO_Reactor>.  If @a timeout ==
00517    * 0, the caller will block until action is possible, else will wait
00518    * until the relative time specified in @a timeout elapses).
00519    */
00520   virtual int notify (ACE_Event_Handler *event_handler = 0,
00521                       ACE_Reactor_Mask mask = ACE_Event_Handler::EXCEPT_MASK,
00522                       ACE_Time_Value *timeout = 0);
00523 
00524   /// No-op.
00525   virtual int dispatch_notifications (int &number_of_active_handles,
00526                                       ACE_Handle_Set &rd_mask);
00527 
00528   /// Returns a handle to the <ACE_Auto_Event>.
00529   virtual ACE_HANDLE get_handle (void) const;
00530 
00531   /// Returns the ACE_HANDLE of the notify pipe on which the reactor
00532   /// is listening for notifications so that other threads can unblock
00533   /// the <Reactor_Impl>
00534   virtual ACE_HANDLE notify_handle (void);
00535 
00536   /// Handle one of the notify call on the <handle>. This could be
00537   /// because of a thread trying to unblock the <Reactor_Impl>
00538   virtual int dispatch_notify (ACE_Notification_Buffer &buffer);
00539 
00540   /// Verify whether the buffer has dispatchable info or not.
00541   virtual int is_dispatchable (ACE_Notification_Buffer &buffer);
00542 
00543   /// Read one of the notify call on the <handle> into the
00544   /// <buffer>. This could be because of a thread trying to unblock
00545   /// the <Reactor_Impl>
00546   virtual int read_notify_pipe (ACE_HANDLE handle,
00547                                 ACE_Notification_Buffer &buffer);
00548 
00549   /**
00550    * Set the maximum number of times that the
00551    * <ACE_WFMO_Reactor_Notify::handle_input> method will iterate and
00552    * dispatch the <ACE_Event_Handlers> that are passed in via the
00553    * notify queue before breaking out of its
00554    * <ACE_Message_Queue::dequeue> loop.  By default, this is set to
00555    * -1, which means "iterate until the queue is empty."  Setting this
00556    * to a value like "1 or 2" will increase "fairness" (and thus
00557    * prevent starvation) at the expense of slightly higher dispatching
00558    * overhead.
00559    */
00560   void max_notify_iterations (int);
00561 
00562   /**
00563    * Get the maximum number of times that the
00564    * <ACE_WFMO_Reactor_Notify::handle_input> method will iterate and
00565    * dispatch the <ACE_Event_Handlers> that are passed in via the
00566    * notify queue before breaking out of its
00567    * <ACE_Message_Queue::dequeue> loop.
00568    */
00569   int max_notify_iterations (void);
00570 
00571   /**
00572    * Purge any notifications pending in this reactor for the specified
00573    * ACE_Event_Handler object. If <eh> == 0, all notifications for all
00574    * handlers are removed (but not any notifications posted just to wake up
00575    * the reactor itself). Returns the number of notifications purged.
00576    * Returns -1 on error.
00577    */
00578   virtual int purge_pending_notifications (ACE_Event_Handler *,
00579                                            ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK);
00580 
00581   /// Dump the state of an object.
00582   virtual void dump (void) const;
00583 
00584 private:
00585   /// Pointer to the wfmo_reactor's timer queue.
00586   ACE_Timer_Queue *timer_queue_;
00587 
00588   /**
00589    * Called when the notification event waited on by
00590    * <ACE_WFMO_Reactor> is signaled.  This dequeues all pending
00591    * <ACE_Event_Handlers> and dispatches them.
00592    */
00593   virtual int handle_signal (int signum, siginfo_t * = 0, ucontext_t * = 0);
00594 
00595   /// An auto event is used so that we can <signal> it to wakeup one
00596   /// thread up (e.g., when the <notify> method is called).
00597   ACE_Auto_Event wakeup_one_thread_;
00598 
00599   /// Message queue that keeps track of pending <ACE_Event_Handlers>.
00600   /// This queue must be thread-safe because it can be called by
00601   /// multiple threads of control.
00602   ACE_Message_Queue<ACE_MT_SYNCH> message_queue_;
00603 
00604   /**
00605    * Keeps track of the maximum number of times that the
00606    * <ACE_WFMO_Reactor_Notify::handle_input> method will iterate and
00607    * dispatch the <ACE_Event_Handlers> that are passed in via the
00608    * notify queue before breaking out of its
00609    * <ACE_Message_Queue::dequeue> loop.  By default, this is set to
00610    * -1, which means "iterate until the queue is empty."
00611    */
00612   int max_notify_iterations_;
00613 };
00614 
00615 /**
00616  * @class ACE_WFMO_Reactor
00617  *
00618  * @brief An object oriented event demultiplexor and event handler.
00619  * ACE_WFMO_Reactor is a Windows-only implementation of the ACE_Reactor
00620  * interface that uses the WaitForMultipleObjects() event demultiplexer.
00621  *
00622  * Like the other ACE Reactors, ACE_WFMO_Reactor can schedule timers.
00623  * It also reacts to signalable handles, such as events (see the documentation
00624  * for WaitForMultipleObjects() for a complete list of signalable handle
00625  * types). Therefore, I/O handles are not directly usable for registering
00626  * for input, output, and exception notification. The exception to this
00627  * is ACE_SOCK-based handles, which can be registered for input, output, and
00628  * exception notification just as with other platforms. See Chapter 4 in
00629  * C++NPv2 for complete details.
00630  *
00631  * Note that changes to the state of ACE_WFMO_Reactor are not
00632  * instantaneous.  Most changes (registration, removal,
00633  * suspension, and resumption of handles, and changes in
00634  * ownership) are made when the ACE_WFMO_Reactor reaches a stable
00635  * state.  Users should be careful, especially when removing
00636  * handlers.  This is because the ACE_WFMO_Reactor will call
00637  * handle_close() on the handler when it is finally removed and
00638  * not when remove_handler() is called.  If the registered handler's pointer
00639  * is not valid when ACE_WFMO_Reactor calls ACE_Event_Handler::handle_close(),
00640  * use the DONT_CALL flag with remove_handler(). Preferably, use dynamically
00641  * allocated event handlers and call "delete this" inside the handle_close()
00642  * hook method.
00643  *
00644  * Note that although multiple threads can concurrently run the
00645  * ACE_WFMO_Reactor event loop, the concept of the reactor "owner" is still
00646  * important. Only the owner thread can expire timers and wait on the
00647  * notifications handle. Thus, be careful to properly set the owner thread
00648  * when spawning threads to run the event loop while you are using timers
00649  * or notifications.
00650  */
00651 class ACE_Export ACE_WFMO_Reactor : public ACE_Reactor_Impl
00652 {
00653 public:
00654   friend class ACE_WFMO_Reactor_Handler_Repository;
00655   friend class ACE_WFMO_Reactor_Test;
00656 
00657   enum
00658   {
00659     /// Default size of the WFMO_Reactor's handle table.
00660     /**
00661      * Two slots will be added to the @a size parameter in the
00662      * constructor and open methods which will store handles used for
00663      * internal management purposes.
00664      */
00665     DEFAULT_SIZE = MAXIMUM_WAIT_OBJECTS - 2
00666   };
00667 
00668   // = Initialization and termination methods.
00669 
00670   /// Initialize ACE_WFMO_Reactor with the default size.
00671   ACE_WFMO_Reactor (ACE_Sig_Handler * = 0,
00672                     ACE_Timer_Queue * = 0,
00673                     ACE_Reactor_Notify * = 0);
00674 
00675   /**
00676    * Initialize ACE_WFMO_Reactor with the specified size.
00677    *
00678    * @param size  The maximum number of handles the reactor can
00679    *              register. The value should not exceed
00680    *              ACE_WFMO_Reactor::DEFAULT_SIZE. Two slots will be
00681    *              added to the @a size parameter which will store handles
00682    *              used for internal management purposes.
00683    */
00684   ACE_WFMO_Reactor (size_t size,
00685                     int unused = 0,
00686                     ACE_Sig_Handler * = 0,
00687                     ACE_Timer_Queue * = 0,
00688                     ACE_Reactor_Notify * = 0);
00689 
00690   /**
00691    * Initialize ACE_WFMO_Reactor with the specified size.
00692    *
00693    * @param size  The maximum number of handles the reactor can
00694    *              register. The value should not exceed
00695    *              ACE_WFMO_Reactor::DEFAULT_SIZE. Two slots will be
00696    *              added to the @a size parameter which will store handles
00697    *              used for internal management purposes.
00698    */
00699   virtual int open (size_t size = ACE_WFMO_Reactor::DEFAULT_SIZE,
00700                     int restart = 0,
00701                     ACE_Sig_Handler * = 0,
00702                     ACE_Timer_Queue * = 0,
00703                     int disable_notify_pipe = 0,
00704                     ACE_Reactor_Notify * = 0);
00705 
00706   /// Returns -1 (not used in this implementation);
00707   virtual int current_info (ACE_HANDLE, size_t & /* size */);
00708 
00709   /// Use a user specified signal handler instead.
00710   virtual int set_sig_handler (ACE_Sig_Handler *signal_handler);
00711 
00712   /// Set a user-specified timer queue.
00713   virtual int timer_queue (ACE_Timer_Queue *tq);
00714 
00715   /// Return the current ACE_Timer_Queue.
00716   virtual ACE_Timer_Queue *timer_queue (void) const;
00717 
00718   /// Close down the ACE_WFMO_Reactor and release all of its resources.
00719   virtual int close (void);
00720 
00721   /// Close down the ACE_WFMO_Reactor and release all of its resources.
00722   virtual ~ACE_WFMO_Reactor (void);
00723 
00724   // = Event loop drivers.
00725 
00726   /**
00727    * This method is not currently implemented.  We recommend that you
00728    * use handle_events (ACE_Time_Value::zero) to get basically the
00729    * same effect, i.e., it won't block the caller if there are no events.
00730    */
00731   virtual int work_pending (const ACE_Time_Value &max_wait_time =  ACE_Time_Value::zero);
00732 
00733   /**
00734    * This event loop driver blocks for up to @a max_wait_time before
00735    * returning.  It will return earlier if timer events, I/O events,
00736    * or signal events occur.  Note that @a max_wait_time can be 0, in
00737    * which case this method blocks indefinitely until events occur.
00738    *
00739    * @a max_wait_time is decremented to reflect how much time this call
00740    * took.  For instance, if a time value of 3 seconds is passed to
00741    * handle_events and an event occurs after 2 seconds,
00742    * @a max_wait_time will equal 1 second.  This can be used if an
00743    * application wishes to handle events for some fixed amount of
00744    * time.
00745    *
00746    * <WaitForMultipleObjects> is used as the demultiplexing call
00747    *
00748    * Returns the total number of I/O and timer ACE_Event_Handlers
00749    * that were dispatched, 0 if the @a max_wait_time elapsed without
00750    * dispatching any handlers, or -1 if an error occurs.
00751    *
00752    * The only difference between <alertable_handle_events> and
00753    * <handle_events> is that in the alertable case, TRUE is passed to
00754    * <WaitForMultipleObjects> for the <bAlertable> option.
00755    */
00756   virtual int handle_events (ACE_Time_Value *max_wait_time = 0);
00757   virtual int alertable_handle_events (ACE_Time_Value *max_wait_time = 0);
00758 
00759   /**
00760    * This method is just like the one above, except the
00761    * @a max_wait_time value is a reference and can therefore never be
00762    * NULL.
00763    *
00764    * The only difference between <alertable_handle_events> and
00765    * <handle_events> is that in the alertable case, TRUE is passed to
00766    * <WaitForMultipleObjects> for the <bAlertable> option.
00767    */
00768   virtual int handle_events (ACE_Time_Value &max_wait_time);
00769   virtual int alertable_handle_events (ACE_Time_Value &max_wait_time);
00770 
00771 
00772   // = Event handling control.
00773 
00774   /**
00775    * Return the status of Reactor.  If this function returns 0, the reactor is
00776    * actively handling events.  If it returns non-zero, <handling_events> and
00777    * <handle_alertable_events> return -1 immediately.
00778    */
00779   virtual int deactivated (void);
00780 
00781   /**
00782    * Control whether the Reactor will handle any more incoming events or not.
00783    * If <do_stop> == 1, the Reactor will be disabled.  By default, a reactor
00784    * is in active state and can be deactivated/reactived as wish.
00785    */
00786   virtual void deactivate (int do_stop);
00787 
00788   // = Register and remove Handlers.
00789 
00790   /**
00791    * Register an ACE_Event_Handler <event_handler>.  Since no Event
00792    * Mask is passed through this interface, it is assumed that the
00793    * <handle> being passed in is an event handle and when the event
00794    * becomes signaled, <WFMO_Reactor> will call handle_signal on
00795    * <event_handler>.  If <handle> == <ACE_INVALID_HANDLE> the
00796    * <ACE_WFMO_Reactor> will call the <get_handle> method of
00797    * <event_handler> to extract the underlying event handle.
00798    */
00799   virtual int register_handler (ACE_Event_Handler *event_handler,
00800                                 ACE_HANDLE event_handle = ACE_INVALID_HANDLE);
00801 
00802   /**
00803    * Register an ACE_Event_Handler <event_handle>.  @a mask specifies
00804    * the network events that the <event_handler> is interested in.  If
00805    * <io_handle> == <ACE_INVALID_HANDLE> the <ACE_WFMO_Reactor> will
00806    * call the <get_handle> method of <event_handler> to extract the
00807    * underlying I/O handle. If the <event_handle> ==
00808    * <ACE_INVALID_HANDLE>, WFMO_Reactor will create an event for
00809    * associating it with the I/O handle. When the <event_handle> is
00810    * signalled, the appropriate <handle_*> callback will be invoked on
00811    * the <Event_Handler>
00812    */
00813   virtual int register_handler (ACE_HANDLE event_handle,
00814                                 ACE_HANDLE io_handle,
00815                                 ACE_Event_Handler *event_handler,
00816                                 ACE_Reactor_Mask mask);
00817 
00818   /**
00819    * This is a simple version of the above <register_handler> method
00820    * where the I/O handle is passed in and the event handle will
00821    * always be created by <WFMO_Reactor>
00822    */
00823   virtual int register_handler (ACE_HANDLE io_handle,
00824                                 ACE_Event_Handler *event_handler,
00825                                 ACE_Reactor_Mask mask);
00826 
00827   /**
00828    * This is a simple version of the above <register_handler> method
00829    * where the I/O handle will always come from <get_handle> on the
00830    * <Event_Handler> and the event handle will always be created by
00831    * <WFMO_Reactor>
00832    */
00833   virtual int register_handler (ACE_Event_Handler *event_handler,
00834                                 ACE_Reactor_Mask mask);
00835 
00836   /// Register <event_handler> with all the <handles> in the
00837   /// <Handle_Set>.
00838   virtual int register_handler (const ACE_Handle_Set &handles,
00839                                 ACE_Event_Handler *event_handler,
00840                                 ACE_Reactor_Mask mask);
00841 
00842   /**
00843    * Register <new_sh> to handle the signal @a signum using the
00844    * <new_disp>.  Returns the <old_sh> that was previously registered
00845    * (if any), along with the <old_disp> of the signal handler.
00846    */
00847   virtual int register_handler (int signum,
00848                                 ACE_Event_Handler *new_sh,
00849                                 ACE_Sig_Action *new_disp = 0,
00850                                 ACE_Event_Handler **old_sh = 0,
00851                                 ACE_Sig_Action *old_disp = 0);
00852 
00853   /// Registers <new_sh> to handle a set of signals <sigset> using the
00854   /// <new_disp>.
00855   virtual int register_handler (const ACE_Sig_Set &sigset,
00856                                 ACE_Event_Handler *new_sh,
00857                                 ACE_Sig_Action *new_disp = 0);
00858 
00859   /**
00860    * Removes <event_handler> from the <ACE_WFMO_Reactor>.  Note that
00861    * the <ACE_WFMO_Reactor> will call the <get_handle> method of
00862    * <event_handler> to extract the underlying handle.  If @a mask ==
00863    * ACE_Event_Handler::DONT_CALL then the <handle_close> method of
00864    * the <event_handler> is not invoked. Note that the <handle> can
00865    * either be the <event_handle> or the <io_handle>
00866    */
00867   virtual int remove_handler (ACE_Event_Handler *event_handler,
00868                               ACE_Reactor_Mask mask);
00869 
00870   /**
00871    * Removes <handle> from the <ACE_WFMO_Reactor>.  If @a mask ==
00872    * ACE_Event_Handler::DONT_CALL then the <handle_close> method of
00873    * the <event_handler> is not invoked. Note that the <handle> can
00874    * either be the <event_handle> or the <io_handle>
00875    *
00876    * For the case of I/O entries, this removes the @a mask binding of
00877    * <Event_Handler> whose handle is <handle> from <WFMO_Reactor>.  If
00878    * there are no more bindings for this <event_handler> then it is
00879    * removed from the WFMO_Reactor.  For simple event entries, mask is
00880    * mostly ignored and the <Event_Handler> is always removed from
00881    * <WFMO_Reactor>
00882    */
00883   virtual int remove_handler (ACE_HANDLE handle,
00884                               ACE_Reactor_Mask mask);
00885 
00886   /**
00887    * Removes all the @a mask bindings for handles in the <handle_set>
00888    * bind of <Event_Handler>.  If there are no more bindings for any
00889    * of these handles then they are removed from WFMO_Reactor.
00890    */
00891   virtual int remove_handler (const ACE_Handle_Set &handle_set,
00892                               ACE_Reactor_Mask);
00893 
00894   /**
00895    * Remove the ACE_Event_Handler currently associated with @a signum.
00896    * <sigkey> is ignored in this implementation since there is only
00897    * one instance of a signal handler.  Install the new disposition
00898    * (if given) and return the previous disposition (if desired by the
00899    * caller).  Returns 0 on success and -1 if @a signum is invalid.
00900    */
00901   virtual int remove_handler (int signum,
00902                               ACE_Sig_Action *new_disp,
00903                               ACE_Sig_Action *old_disp = 0,
00904                               int sigkey = -1);
00905 
00906   /// Calls <remove_handler> for every signal in <sigset>.
00907   virtual int remove_handler (const ACE_Sig_Set &sigset);
00908 
00909   // = Suspend and resume Handlers.
00910 
00911   /// Suspend <event_handler> temporarily.  Use
00912   /// <ACE_Event_Handler::get_handle> to get the handle.
00913   virtual int suspend_handler (ACE_Event_Handler *event_handler);
00914 
00915   /// Suspend <handle> temporarily.
00916   virtual int suspend_handler (ACE_HANDLE handle);
00917 
00918   /// Suspend all <handles> in handle set temporarily.
00919   virtual int suspend_handler (const ACE_Handle_Set &handles);
00920 
00921   /// Suspend all <handles> temporarily.
00922   virtual int suspend_handlers (void);
00923 
00924   /// Resume <event_handler>. Use <ACE_Event_Handler::get_handle> to
00925   /// get the handle.
00926   virtual int resume_handler (ACE_Event_Handler *event_handler);
00927 
00928   /// Resume <handle>.
00929   virtual int resume_handler (ACE_HANDLE handle);
00930 
00931   /// Resume all <handles> in handle set.
00932   virtual int resume_handler (const ACE_Handle_Set &handles);
00933 
00934   /// Resume all <handles>.
00935   virtual int resume_handlers (void);
00936 
00937   /// Does the reactor allow the application to resume the handle on
00938   /// its own ie. can it pass on the control of handle resumption to
00939   /// the application. A positive value indicates that the handlers
00940   /// are application resumable. A value of 0 indicates otherwise.
00941   virtual int resumable_handler (void);
00942 
00943   /**
00944    * Return 1 if we any event associations were made by the reactor
00945    * for the handles that it waits on, 0 otherwise. Since the
00946    * WFMO_Reactor does use event associations, this function always
00947    * return 1.
00948    */
00949   virtual int uses_event_associations (void);
00950 
00951   // Timer management.
00952 
00953   /**
00954    * Schedule an ACE_Event_Handler that will expire after an amount
00955    * of time.  The return value of this method, a timer_id value,
00956    * uniquely identifies the event_handler in the ACE_Reactor's
00957    * internal list of timers.
00958    * This timer_id value can be used to cancel the timer
00959    * with the cancel_timer() call.
00960    *
00961    * @see cancel_timer()
00962    * @see reset_timer_interval()
00963    *
00964    * @param event_handler  event handler to schedule on reactor
00965    * @param arg   argument passed to the handle_timeout() method of  event_handler
00966    * @param delay  time interval after which the timer will expire
00967    * @param interval  time interval after which the timer will be automatically rescheduled
00968    * @return -1 on failure, a timer_id value on success
00969    */
00970   virtual long schedule_timer (ACE_Event_Handler *event_handler,
00971                                const void *arg,
00972                                const ACE_Time_Value &delay,
00973                                const ACE_Time_Value &interval = ACE_Time_Value::zero);
00974 
00975   /**
00976    * Resets the interval of the timer represented by @a timer_id to
00977    * @a interval, which is specified in relative time to the current
00978    * <gettimeofday>.  If @a interval is equal to
00979    * ACE_Time_Value::zero, the timer will become a non-rescheduling
00980    * timer.  Returns 0 if successful, -1 if not.
00981    */
00982   virtual int reset_timer_interval (long timer_id,
00983                                     const ACE_Time_Value &interval);
00984 
00985   /// Cancel all Event_Handlers that match the address of
00986   /// <event_handler>.  Returns number of handler's cancelled.
00987   virtual int cancel_timer (ACE_Event_Handler *event_handler,
00988                             int dont_call_handle_close = 1);
00989 
00990   /**
00991    * Cancel the single Event_Handler that matches the @a timer_id value
00992    * (which was returned from the schedule method).  If arg is
00993    * non-NULL then it will be set to point to the ``magic cookie''
00994    * argument passed in when the Event_Handler was registered.  This
00995    * makes it possible to free up the memory and avoid memory leaks.
00996    * Returns 1 if cancellation succeeded and 0 if the @a timer_id
00997    * wasn't found.
00998    */
00999   virtual int cancel_timer (long timer_id,
01000                             const void **arg = 0,
01001                             int dont_call_handle_close = 1);
01002 
01003   // = High-level Event_Handler scheduling operations
01004 
01005   /**
01006    * Add @a masks_to_be_added to the <event_handler>'s entry in
01007    * WFMO_Reactor.  <event_handler> must already have been registered
01008    * with WFMO_Reactor.
01009    */
01010   virtual int schedule_wakeup (ACE_Event_Handler *event_handler,
01011                                ACE_Reactor_Mask masks_to_be_added);
01012 
01013   /**
01014    * Add @a masks_to_be_added to the @a handle's entry in WFMO_Reactor.
01015    * The Event_Handler associated with <handle> must already have been
01016    * registered with WFMO_Reactor.
01017    */
01018   virtual int schedule_wakeup (ACE_HANDLE handle,
01019                                ACE_Reactor_Mask masks_to_be_added);
01020 
01021   /**
01022    * Remove <masks_to_be_deleted> to the <handle>'s entry in
01023    * WFMO_Reactor.  The Event_Handler associated with <handle> must
01024    * already have been registered with WFMO_Reactor.
01025    */
01026   virtual int cancel_wakeup (ACE_Event_Handler *event_handler,
01027                              ACE_Reactor_Mask masks_to_be_deleted);
01028 
01029   /**
01030    * Remove <masks_to_be_deleted> to the <handle>'s entry in
01031    * WFMO_Reactor.  The Event_Handler associated with <handle> must
01032    * already have been registered with WFMO_Reactor.
01033    */
01034   virtual int cancel_wakeup (ACE_HANDLE handle,
01035                              ACE_Reactor_Mask masks_to_be_deleted);
01036 
01037   // = Notification methods.
01038 
01039   /**
01040    * Wakeup one <ACE_WFMO_Reactor> thread if it is currently blocked
01041    * in <WaitForMultipleObjects>.  The ACE_Time_Value indicates how
01042    * long to blocking trying to notify the <WFMO_Reactor>.  If
01043    * @a timeout == 0, the caller will block until action is possible,
01044    * else will wait until the relative time specified in @a timeout
01045    * elapses).
01046    */
01047   virtual int notify (ACE_Event_Handler * = 0,
01048                       ACE_Reactor_Mask = ACE_Event_Handler::EXCEPT_MASK,
01049                       ACE_Time_Value * = 0);
01050 
01051   /**
01052    * Set the maximum number of times that the
01053    * <ACE_WFMO_Reactor_Notify::handle_input> method will iterate and
01054    * dispatch the <ACE_Event_Handlers> that are passed in via the
01055    * notify queue before breaking out of its
01056    * <ACE_Message_Queue::dequeue> loop.  By default, this is set to
01057    * -1, which means "iterate until the queue is empty."  Setting this
01058    * to a value like "1 or 2" will increase "fairness" (and thus
01059    * prevent starvation) at the expense of slightly higher dispatching
01060    * overhead.
01061    */
01062   virtual void max_notify_iterations (int);
01063 
01064   /**
01065    * Get the maximum number of times that the
01066    * <ACE_WFMO_Reactor_Notify::handle_input> method will iterate and
01067    * dispatch the <ACE_Event_Handlers> that are passed in via the
01068    * notify queue before breaking out of its
01069    * <ACE_Message_Queue::dequeue> loop.
01070    */
01071   virtual int max_notify_iterations (void);
01072 
01073   /**
01074    * Purge any notifications pending in this reactor for the specified
01075    * ACE_Event_Handler object. Returns the number of notifications
01076    * purged. Returns -1 on error.
01077    */
01078   virtual int purge_pending_notifications (ACE_Event_Handler * = 0,
01079                                            ACE_Reactor_Mask    = ACE_Event_Handler::ALL_EVENTS_MASK);
01080 
01081   // = Assorted helper methods.
01082 
01083   /**
01084    * Return the Event_Handler associated with <handle>.  Return 0 if
01085    * <handle> is not registered.
01086    */
01087   ACE_Event_Handler *find_handler (ACE_HANDLE handle);
01088 
01089   /**
01090    * Check to see if <handle> is associated with a valid Event_Handler
01091    * bound to @a mask.  Return the <event_handler> associated with this
01092    * @a handler if <event_handler> != 0.
01093    */
01094   virtual int handler (ACE_HANDLE handle,
01095                        ACE_Reactor_Mask mask,
01096                        ACE_Event_Handler **event_handler = 0);
01097 
01098   /**
01099    * Check to see if @a signum is associated with a valid Event_Handler
01100    * bound to a signal.  Return the <event_handler> associated with
01101    * this @a handler if <event_handler> != 0.
01102    */
01103   virtual int handler (int signum,
01104                        ACE_Event_Handler ** = 0);
01105 
01106   /// Returns true if WFMO_Reactor has been successfully initialized, else
01107   /// false.
01108   virtual bool initialized (void);
01109 
01110   /// Returns the current size of the WFMO_Reactor's internal
01111   /// descriptor table.
01112   virtual size_t size (void) const;
01113 
01114   /// Returns a reference to the WFMO_Reactor's internal lock.
01115   virtual ACE_Lock &lock (void);
01116 
01117   /// Wake up all threads in WaitForMultipleObjects so that they can
01118   /// reconsult the handle set
01119   virtual void wakeup_all_threads (void);
01120 
01121   /**
01122    * Transfers ownership of the WFMO_Reactor to the <new_owner>. The
01123    * transfer will not complete until all threads are ready (just like
01124    * the handle set).
01125    */
01126   virtual int owner (ACE_thread_t new_owner, ACE_thread_t *old_owner = 0);
01127 
01128   /// Return the ID of the "owner" thread.
01129   virtual int owner (ACE_thread_t *owner);
01130 
01131   /// Get the existing restart value.
01132   virtual int restart (void);
01133 
01134   /// Set a new value for restart and return the original value.
01135   virtual int restart (int r);
01136 
01137   /// Not implemented
01138   virtual void requeue_position (int);
01139 
01140   /// Not implemented
01141   virtual int requeue_position (void);
01142 
01143   // = Low-level wait_set mask manipulation methods.
01144 
01145   /**
01146    * Modify @a masks of the <event_handler>'s entry in WFMO_Reactor
01147    * depending upon <operation>.  <event_handler> must already have
01148    * been registered with WFMO_Reactor.
01149    */
01150   virtual int mask_ops (ACE_Event_Handler *event_handler,
01151                         ACE_Reactor_Mask masks,
01152                         int operation);
01153 
01154   /**
01155    * Modify @a masks of the <handle>'s entry in WFMO_Reactor depending
01156    * upon <operation>.  <handle> must already have been registered
01157    * with WFMO_Reactor.
01158    */
01159   virtual int mask_ops (ACE_HANDLE handle,
01160                         ACE_Reactor_Mask masks,
01161                         int ops);
01162 
01163   // = Low-level ready_set mask manipulation methods.
01164 
01165   /// Not implemented
01166   virtual int ready_ops (ACE_Event_Handler *event_handler,
01167                          ACE_Reactor_Mask mask,
01168                          int ops);
01169 
01170   /// Not implemented
01171   virtual int ready_ops (ACE_HANDLE handle,
01172                          ACE_Reactor_Mask,
01173                          int ops);
01174 
01175   /// Declare the dynamic allocation hooks.
01176   ACE_ALLOC_HOOK_DECLARE;
01177 
01178   /// Dump the state of an object.
01179   virtual void dump (void) const;
01180 
01181 protected:
01182   /// Registration workhorse
01183   virtual int register_handler_i (ACE_HANDLE event_handle,
01184                                   ACE_HANDLE io_handle,
01185                                   ACE_Event_Handler *event_handler,
01186                                   ACE_Reactor_Mask mask);
01187 
01188   /// Event handling workhorse
01189   virtual int event_handling (ACE_Time_Value *max_wait_time = 0,
01190                               int alertable = 0);
01191 
01192   /// Bit masking workhorse
01193   virtual int mask_ops_i (ACE_HANDLE io_handle,
01194                           ACE_Reactor_Mask masks,
01195                           int operation);
01196 
01197   /// Return the ID of the "owner" thread. Does not do any locking.
01198   virtual ACE_thread_t owner_i (void);
01199 
01200   /// Wait up to @a max_wait_time until it's ok to enter
01201   /// WaitForMultipleObjects. Returns 1 (and holding lock_) if ok to wait;
01202   /// -1 (and not holding lock_) if not.
01203   virtual int ok_to_wait (ACE_Time_Value *max_wait_time,
01204                           int alertable);
01205 
01206   /// Wait for timer and I/O events to occur.
01207   virtual DWORD wait_for_multiple_events (int timeout,
01208                                           int alertable);
01209 
01210   /// Check for activity on remaining handles.
01211   virtual DWORD poll_remaining_handles (DWORD slot);
01212 
01213   /// Expire timers. Only the owner thread does useful stuff in this
01214   /// function.
01215   virtual int expire_timers (void);
01216 
01217   /// Dispatches the timers and I/O handlers.
01218   virtual int dispatch (DWORD wait_status);
01219 
01220   /// Protect against structured exceptions caused by user code when
01221   /// dispatching handles
01222   virtual int safe_dispatch (DWORD wait_status);
01223 
01224   /**
01225    * Dispatches any active handles from handles_[@a slot] to
01226    * handles_[active_handles_] using <WaitForMultipleObjects> to poll
01227    * through our handle set looking for active handles.
01228    */
01229   virtual int dispatch_handles (DWORD slot);
01230 
01231   /// Dispatches a single handler. Returns 0 on success, -1 if the
01232   /// handler was removed.
01233   virtual int dispatch_handler (DWORD slot,
01234                                 DWORD max_handlep1);
01235 
01236   /// Dispatches a single handler.  Returns 0 on success, -1 if the
01237   /// handler was removed.
01238   virtual int simple_dispatch_handler (DWORD slot,
01239                                        ACE_HANDLE event_handle);
01240 
01241   /// Dispatches a single handler. Returns 0 on success, -1 if the
01242   /// handler was removed.
01243   virtual int complex_dispatch_handler (DWORD slot,
01244                                         ACE_HANDLE event_handle);
01245 
01246   /// Dispatches window messages. Noop for WFMO_Reactor.
01247   virtual int dispatch_window_messages (void);
01248 
01249   virtual ACE_Reactor_Mask upcall (ACE_Event_Handler *event_handler,
01250                                    ACE_HANDLE io_handle,
01251                                    WSANETWORKEVENTS &events);
01252 
01253   /// Used to caluculate the next timeout
01254   virtual int calculate_timeout (ACE_Time_Value *time);
01255 
01256   /// Update the state of the handler repository
01257   virtual int update_state (void);
01258 
01259   /// Check to see if we have a new owner
01260   virtual int new_owner (void);
01261 
01262   /// Set owner to new owner
01263   virtual int change_owner (void);
01264 
01265   /// Handle signals without requiring global/static variables.
01266   ACE_Sig_Handler *signal_handler_;
01267 
01268   /// Keeps track of whether we should delete the signal handler (if we
01269   /// didn't create it, then we don't delete it).
01270   bool delete_signal_handler_;
01271 
01272   /// Defined as a pointer to allow overriding by derived classes...
01273   ACE_Timer_Queue *timer_queue_;
01274 
01275   /// Keeps track of whether we should delete the timer queue (if we
01276   /// didn't create it, then we don't delete it).
01277   bool delete_timer_queue_;
01278 
01279   /// Keeps track of whether we should delete the handler repository
01280   bool delete_handler_rep_;
01281 
01282   /// Used when <notify> is called.
01283   ACE_Reactor_Notify *notify_handler_;
01284 
01285   /// Keeps track of whether we should delete the notify handler.
01286   bool delete_notify_handler_;
01287 
01288   /**
01289    * Synchronization for the ACE_WFMO_Reactor.
01290    *
01291    * A Process Mutex is used here because of two reasons:
01292    * (a) The implementation of ACE_Thread_Mutex uses CriticalSections
01293    *     CriticalSections are not waitable using ::WaitForMultipleObjects
01294    * (b) This is really not a process mutex because it is not
01295    *     named. No other process can use this mutex.
01296    */
01297   ACE_Process_Mutex lock_;
01298 
01299   /// Adapter used to return internal lock to outside world.
01300   ACE_Lock_Adapter<ACE_Process_Mutex> lock_adapter_;
01301 
01302   /// Table that maps <ACE_HANDLEs> to <ACE_Event_Handler *>'s.
01303   ACE_WFMO_Reactor_Handler_Repository handler_rep_;
01304 
01305   /// A manual event used to block threads from proceeding into
01306   /// WaitForMultipleObjects
01307   ACE_Manual_Event ok_to_wait_;
01308 
01309   /**
01310    * A manual event is used so that we can wake everyone up (e.g.,
01311    * when <ACE_Event_Handlers> are bounded and unbound from the
01312    * handler repository).
01313    */
01314   ACE_Manual_Event wakeup_all_threads_;
01315 
01316   /// Used when <wakeup_all_threads_> is signaled
01317   ACE_Wakeup_All_Threads_Handler wakeup_all_threads_handler_;
01318 
01319   /// The changing thread waits on this event, till all threads are not
01320   /// active anymore
01321   ACE_Auto_Event waiting_to_change_state_;
01322 
01323   /// Count of currently active threads
01324   size_t active_threads_;
01325 
01326   /**
01327    * The thread which is "owner" of the WFMO_Reactor. The owner
01328    * concept is used because we don't want multiple threads to try to
01329    * expire timers. Therefore the "owner" thread is the only one
01330    * allowed to expire timers. Also, the owner thread is the only
01331    * thread which waits on the notify handle. Note that the ownership
01332    * can be transferred.
01333    */
01334   ACE_thread_t owner_;
01335 
01336   /// The owner to be of the WFMO_Reactor
01337   ACE_thread_t new_owner_;
01338 
01339   /// This is the thread which is responsible for the changing the
01340   /// state of the <WFMO_Reactor> handle set
01341   ACE_thread_t change_state_thread_;
01342 
01343   /// This is an array of ACE_HANDLEs which keep track of the <lock_>
01344   /// and <ok_to_wait_> handles
01345   ACE_HANDLE atomic_wait_array_ [2];
01346 
01347   /// This flag is used to keep track of whether we are already closed.
01348   bool open_for_business_;
01349 
01350   /// This flag is used to keep track of whether we are actively handling
01351   /// events or not.
01352   sig_atomic_t deactivated_;
01353 
01354 private:
01355   /// Deny access since member-wise won't work...
01356   ACE_WFMO_Reactor (const ACE_WFMO_Reactor &);
01357   ACE_WFMO_Reactor &operator = (const ACE_WFMO_Reactor &);
01358 };
01359 
01360 ACE_END_VERSIONED_NAMESPACE_DECL
01361 
01362 #if defined (__ACE_INLINE__)
01363 #include "ace/WFMO_Reactor.inl"
01364 #endif /* __ACE_INLINE__ */
01365 
01366 #endif /* ACE_WIN32 */
01367 #include /**/ "ace/post.h"
01368 #endif /* ACE_WFMO_REACTOR_H */

Generated on Tue Feb 2 17:18:44 2010 for ACE by  doxygen 1.4.7