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

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

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