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

Generated on Sun Jan 27 12:05:43 2008 for ACE by doxygen 1.3.6