WFMO_Reactor.h

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

Generated on Thu Nov 9 09:42:09 2006 for ACE by doxygen 1.3.6