/* -*- C++ -*- */ // $Id$ // ============================================================================ // // = LIBRARY // ace // // = FILENAME // WFMO_Reactor.h // // = AUTHOR // Irfan Pyarali, Tim Harrison, and Doug Schmidt // // ============================================================================ #if !defined (ACE_WFMO_REACTOR_H) #define ACE_WFMO_REACTOR_H #include "ace/Signal.h" #include "ace/Timer_Queue.h" #include "ace/Event_Handler.h" #include "ace/Synch.h" #include "ace/Reactor_Impl.h" #include "ace/Message_Queue.h" // Forward decl. class ACE_WFMO_Reactor; class ACE_Handle_Set; class ACE_Export ACE_Wakeup_All_Threads_Handler : public ACE_Event_Handler { // = TITLE // // This is a helper class whose sole purpose is to handle events // on wakeup_all_threads_> // public: virtual int handle_signal (int signum, siginfo_t * = 0, ucontext_t * = 0); // Called when the wakeup_all_threads_> }; class ACE_Export ACE_WFMO_Reactor_Handler_Repository { // = TITLE // // Used to map s onto the appropriate // * and other information. // public: friend class ACE_WFMO_Reactor; class Common_Info { // = TITLE // // This struct contains the necessary information for every // entry. The reason the event is not in this // structure is because we need to pass an event array into // WaitForMultipleObjects and therefore keeping the events // seperate makes sense. // public: int io_entry_; // This indicates whether this entry is for I/O or for a regular // event ACE_Event_Handler *event_handler_; // The assosiated ACE_HANDLE io_handle_; // The I/O handle related to the . This entry is // only valid if the flag is true. long network_events_; // This is the set of events that the is // interested in This entry is only valid if the flag // is true. int delete_event_; // This flag indicates that created the event on // behalf of the user. Therefore we need to clean this up when the // removes itself from . This entry // is only valid if the flag is true. Common_Info (void); // Constructor used for initializing the structure void reset (void); // Reset the state of the structure void set (int io_entry, ACE_Event_Handler *event_handler, ACE_HANDLE io_handle, long network_events, int delete_event); // Set the structure to these new values void set (Common_Info &common_info); // Set the structure to these new values }; class Current_Info : public Common_Info { // = TITLE // // This structure inherits from the common structure to add // information for current entries. // public: int delete_entry_; // This is set when the entry needed to be deleted. ACE_Reactor_Mask close_masks_; // These are the masks related to for the // . int suspend_entry_; // This is set when the entry needed to be suspended. Current_Info (void); // Default constructor void reset (void); // Reset the state of the structure void set (int io_entry, ACE_Event_Handler *event_handler, ACE_HANDLE io_handle, long network_events, int delete_event, int delete_entry = 0, ACE_Reactor_Mask close_masks = 0, int suspend_entry = 0); // Set the structure to these new values void set (Common_Info &common_info, int delete_entry = 0, ACE_Reactor_Mask close_masks = 0, int suspend_entry = 0); // Set the structure to these new values }; class To_Be_Added_Info : public Common_Info { // = TITLE // // This structure inherits from the common structure to add // information for entries. // public: ACE_HANDLE event_handle_; // Handle for the event To_Be_Added_Info (void); // Default constructor void reset (void); // Reset the state of the structure void set (ACE_HANDLE event_handle, int io_entry, ACE_Event_Handler *event_handler, ACE_HANDLE io_handle, long network_events, int delete_event); // Set the structure to these new values void set (ACE_HANDLE event_handle, Common_Info &common_info); // Set the structure to these new values }; class Suspended_Info : public Common_Info { // = TITLE // // This structure inherits from the common structure to add // information for suspended entries. // public: ACE_HANDLE event_handle_; // Handle for the event int delete_entry_; // This is set when the entry needed to be deleted. ACE_Reactor_Mask close_masks_; // These are the masks related to for the // . int resume_entry_; // This is set when the entry needed to be resumed. Suspended_Info (void); // Constructor used for initializing the structure void reset (void); // Reset the state of the structure void set (ACE_HANDLE event_handle, int io_entry, ACE_Event_Handler *event_handler, ACE_HANDLE io_handle, long network_events, int delete_event, int resume = 0, int delete_entry = 0, ACE_Reactor_Mask close_masks = 0); // Set the structure to these new values void set (ACE_HANDLE event_handle, Common_Info &common_info, int resume = 0, int delete_entry = 0, ACE_Reactor_Mask close_masks = 0); // Set the structure to these new values }; ACE_WFMO_Reactor_Handler_Repository (ACE_WFMO_Reactor &wfmo_reactor); // Constructor. virtual ~ACE_WFMO_Reactor_Handler_Repository (void); // Destructor. int open (size_t size); // Initialize the repository of the approriate . int close (void); // Close down the handler repository. // = Search structure operations. int bind (ACE_HANDLE, ACE_Event_Handler *); // Bind the to the . This is for // the simple event entry. int bind_i (int io_entry, ACE_Event_Handler *event_handler, long network_events, ACE_HANDLE io_handle, ACE_HANDLE event_handle, int delete_event); // Insert I/O entry into the system. This method // assumes that the lock are head *before* this method is invoked. int unbind (ACE_HANDLE, ACE_Reactor_Mask mask); // Remove the binding of in accordance with the . int unbind_i (ACE_HANDLE, ACE_Reactor_Mask mask, int &changes_required); // Non-lock-grabbing version of void unbind_all (void); // Remove all bindings of tuples. // = Sanity checking. // Check the to make sure it's a valid ACE_HANDLE int invalid_handle (ACE_HANDLE handle) const; // = Accessors. size_t max_handlep1 (void) const; // Maximum ACE_HANDLE value, plus 1. ACE_HANDLE *handles (void) const; // Pointer to the beginning of the current array of // *'s. Current_Info *current_info (void) const; // Pointer to the beginning of the current array of // *'s. virtual int changes_required (void); // Check if changes to the handle set are required. virtual int make_changes (void); // Make changes to the handle set int scheduled_for_deletion (size_t index) const; // Check to see if has been scheduled for deletion int add_network_events_i (ACE_Reactor_Mask mask, ACE_HANDLE io_handle, long &new_mask, ACE_HANDLE &event_handle, int &delete_event); // This method is used to calculate the network mask after a // register request to . Note that because the // may already be in the handler repository, we may // have to find the old event and the old network events void remove_network_events_i (long &existing_masks, ACE_Reactor_Mask to_be_removed_masks); // This method is used to change the network mask left (if any) // after a remove request to int suspend_handler_i (ACE_HANDLE handle, int &changes_required); // Temporarily suspend entry int resume_handler_i (ACE_HANDLE handle, int &changes_required); // Resume suspended entry int handle_deletions (void); // Remove handles from the handle set int handle_additions (void); // Add handles to the handle set int remove_handler_i (size_t index, ACE_Reactor_Mask mask); // Removes the at from the table. int remove_suspended_handler_i (size_t index, ACE_Reactor_Mask mask); // Removes the at from the table. void dump (void) const; // Dump the state of an object. protected: ACE_WFMO_Reactor &wfmo_reactor_; // Reference to our . size_t max_size_; // Maximum number of handles. size_t max_handlep1_; // A count of the number of active handles. ACE_HANDLE *current_handles_; // Array of passed to . This // is not part of the structure as the handle array needs to be // passed directly to . Current_Info *current_info_; // Array of current entries in the table To_Be_Added_Info *to_be_added_info_; // Information for entries to be added Suspended_Info *current_suspended_info_; // Currently suspended handles size_t suspended_handles_; // Number of currently suspended handles size_t handles_to_be_suspended_; // Number of records to be suspended size_t handles_to_be_resumed_; // Number of records to be resumed size_t handles_to_be_deleted_; // Number of records to be deleted size_t handles_to_be_added_; // Number of records to be added }; class ACE_Export ACE_WFMO_Reactor_Notify : public ACE_Event_Handler { // = TITLE // // Unblock the from its event loop, passing // it an optional to dispatch. // // = DESCRIPTION // // This implementation is necessary for cases where the // is run in a multi-threaded program. In // this case, we need to be able to unblock // WaitForMultipleObjects() when updates occur other than in the // main thread. To do this, we signal an // auto-reset event the is listening on. If // an and is passed to // , the appropriate method is dispatched. // public: ACE_WFMO_Reactor_Notify (void); // Constructor int open (ACE_WFMO_Reactor &wfmo_reactor, ACE_Timer_Queue *timer_queue); // Initialization. is stored to call gettimeofday. int notify (ACE_Event_Handler *event_handler = 0, ACE_Reactor_Mask mask = ACE_Event_Handler::EXCEPT_MASK, ACE_Time_Value *timeout = 0); // Special trick to unblock WaitForMultipleObjects() when updates // occur. All we do is enqueue and onto the // and wakeup the WFMO_Reactor by signaling its // handle. The indicates how long to // blocking trying to notify the . If == 0, // the caller will block until action is possible, else will wait // until the relative time specified in elapses). virtual ACE_HANDLE get_handle (void) const; // Returns a handle to the . void max_notify_iterations (int); // Set the maximum number of times that the // method will iterate and // dispatch the that are passed in via the // notify queue before breaking out of its // loop. By default, this is set to // -1, which means "iterate until the queue is empty." Setting this // to a value like "1 or 2" will increase "fairness" (and thus // prevent starvation) at the expense of slightly higher dispatching // overhead. int max_notify_iterations (void); // Get the maximum number of times that the // method will iterate and // dispatch the that are passed in via the // notify queue before breaking out of its // loop. private: ACE_Timer_Queue *timer_queue_; // Pointer to the wfmo_reactor's timer queue. virtual int handle_signal (int signum, siginfo_t * = 0, ucontext_t * = 0); // Called when the notification event waited on by // is signaled. This dequeues all pending // and dispatches them. ACE_Auto_Event wakeup_one_thread_; // An auto event is used so that we can it to wakeup one // thread up (e.g., when the method is called). #if defined (ACE_WIN32) // because Sun C++ 4.1 can't cope with this declaration: ACE_Message_Queue message_queue_; #endif /* ACE_WIN32 */ // Message queue that keeps track of pending . // This queue must be thread-safe because it can be called by // multiple threads of control. int max_notify_iterations_; // Keeps track of the maximum number of times that the // method will iterate and // dispatch the that are passed in via the // notify queue before breaking out of its // loop. By default, this is set to // -1, which means "iterate until the queue is empty." }; #if defined (ACE_WIN32) class ACE_Export ACE_WFMO_Reactor : public ACE_Reactor_Impl { // = TITLE // // An object oriented event demultiplexor and event handler // WFMO_Reactor for Win32 WaitForMultipleObjects // // = DESCRIPTION // // The ACE_WFMO_Reactor is an object-oriented event // demultiplexor and event handler Reactor. The sources of // events that the ACE_WFMO_Reactor waits for and dispatches // includes I/O events, general Win32 synchronization events // (such as mutexes, semaphores, threads, etc.) and timer // events. // // Note that changes to the state of WFMO_Reactor are not // instantaneous. Most changes (registration, removal, // suspension, and resumption of handles, and changes in // ownership) are made when the WFMO_Reactor reaches a stable // state. Users should be careful, specially when removing // handlers. This is because the WFMO_Reactor will call // handle_close on the handler when it is finally removed and // not when remove_handler is called. If the handler is not // going to be around when the WFMO_Reactor calls // handler->handle_close(), use the DONT_CALL flag with // remove_handler(). Or else, dynamically allocate the handler, // and then call "delete this" inside handler->handle_close(). // public: friend class ACE_WFMO_Reactor_Handler_Repository; friend class ACE_WFMO_Reactor_Test; enum { DEFAULT_SIZE = MAXIMUM_WAIT_OBJECTS - 2 // Default size of the WFMO_Reactor's handle table. Two slots will // be added to the parameter in the constructor and open // methods which will store handles used for internal management // purposes. }; // = Initialization and termination methods. ACE_WFMO_Reactor (ACE_Sig_Handler * = 0, ACE_Timer_Queue * = 0); // Initialize with the default size. ACE_WFMO_Reactor (size_t size, int unused = 0, ACE_Sig_Handler * = 0, ACE_Timer_Queue * = 0); // Initialize with size . Two slots will // be added to the parameter which will store handles used // for internal management purposes. virtual int open (size_t size = DEFAULT_SIZE, int restart = 0, ACE_Sig_Handler * = 0, ACE_Timer_Queue * = 0); // Initialize with size . Two slots will // be added to the parameter which will store handles used // for internal management purposes. virtual int set_sig_handler (ACE_Sig_Handler *signal_handler); // Use a user specified signal handler instead. virtual int set_timer_queue (ACE_Timer_Queue *timer_queue); // Use a user specified timer queue instead. virtual int close (void); // Close down the WFMO_Reactor and release all of its resources. virtual ~ACE_WFMO_Reactor (void); // Close down the WFMO_Reactor and release all of its resources. // = Event loop drivers. virtual int handle_events (ACE_Time_Value *max_wait_time = 0); virtual int alertable_handle_events (ACE_Time_Value *max_wait_time = 0); // This event loop driver blocks for up to before // returning. It will return earlier if timer events, I/O events, // or signal events occur. Note that can be 0, in // which case this method blocks indefinitely until events occur. // // is decremented to reflect how much time this call // took. For instance, if a time value of 3 seconds is passed to // handle_events and an event occurs after 2 seconds, // will equal 1 second. This can be used if an // application wishes to handle events for some fixed amount of // time. // // is used as the demultiplexing call // // Returns the total number of s that were // dispatched, 0 if the elapsed without dispatching // any handlers, or -1 if an error occurs. // // The only difference between and // is that in the alertable case, TRUE is passed to // for the option. virtual int handle_events (ACE_Time_Value &max_wait_time); virtual int alertable_handle_events (ACE_Time_Value &max_wait_time); // This method is just like the one above, except the // value is a reference and can therefore never be // NULL. // // The only difference between and // is that in the alertable case, TRUE is passed to // for the option. // = Register and remove Handlers. virtual int register_handler (ACE_Event_Handler *event_handler, ACE_HANDLE event_handle = ACE_INVALID_HANDLE); // Register an . Since no Event // Mask is passed through this interface, it is assumed that the // being passed in is an event handle and when the event // becomes signaled, will call handle_signal on // . If == the // will call the method of // to extract the underlying event handle. virtual int register_handler (ACE_HANDLE event_handle, ACE_HANDLE io_handle, ACE_Event_Handler *event_handler, ACE_Reactor_Mask mask); // Register an . specifies // the network events that the is interested in. If // == the will // call the method of to extract the // underlying I/O handle. If the == // , WFMO_Reactor will create an event for // associating it with the I/O handle. When the is // signalled, the appropriate callback will be invoked on // the virtual int register_handler (ACE_HANDLE io_handle, ACE_Event_Handler *event_handler, ACE_Reactor_Mask mask); // This is a simple version of the above method // where the I/O handle is passed in and the event handle will // always be created by virtual int register_handler (ACE_Event_Handler *event_handler, ACE_Reactor_Mask mask); // This is a simple version of the above method // where the I/O handle will always come from on the // and the event handle will always be created by // virtual int register_handler (const ACE_Handle_Set &handles, ACE_Event_Handler *event_handler, ACE_Reactor_Mask mask); // Register with all the in the // . virtual int register_handler (int signum, ACE_Event_Handler *new_sh, ACE_Sig_Action *new_disp = 0, ACE_Event_Handler **old_sh = 0, ACE_Sig_Action *old_disp = 0); // Register to handle the signal using the // . Returns the that was previously registered // (if any), along with the of the signal handler. virtual int register_handler (const ACE_Sig_Set &sigset, ACE_Event_Handler *new_sh, ACE_Sig_Action *new_disp = 0); // Registers to handle a set of signals using the // . virtual int remove_handler (ACE_Event_Handler *event_handler, ACE_Reactor_Mask mask); // Removes from the . Note that // the will call the method of // to extract the underlying handle. If == // then the method of // the is not invoked. Note that the can // either be the or the virtual int remove_handler (ACE_HANDLE handle, ACE_Reactor_Mask mask); // Removes from the . If == // then the method of // the is not invoked. Note that the can // either be the or the // // For the case of I/O entries, this removes the binding of // whose handle is from . If // there are no more bindings for this then it is // removed from the WFMO_Reactor. For simple event entries, mask is // mostly ignored and the is always removed from // virtual int remove_handler (const ACE_Handle_Set &handle_set, ACE_Reactor_Mask); // Removes all the bindings for handles in the // bind of . If there are no more bindings for any // of these handles then they are removed from WFMO_Reactor. virtual int remove_handler (int signum, ACE_Sig_Action *new_disp, ACE_Sig_Action *old_disp = 0, int sigkey = -1); // Remove the ACE_Event_Handler currently associated with . // is ignored in this implementation since there is only // one instance of a signal handler. Install the new disposition // (if given) and return the previous disposition (if desired by the // caller). Returns 0 on success and -1 if is invalid. virtual int remove_handler (const ACE_Sig_Set &sigset); // Calls for every signal in . // = Suspend and resume Handlers. virtual int suspend_handler (ACE_Event_Handler *event_handler); // Suspend temporarily. Use // get_handle()> to get the handle. virtual int suspend_handler (ACE_HANDLE handle); // Suspend temporarily. virtual int suspend_handler (const ACE_Handle_Set &handles); // Suspend all in handle set temporarily. virtual int suspend_handlers (void); // Suspend all temporarily. virtual int resume_handler (ACE_Event_Handler *event_handler); // Resume . Use get_handle()> to get // the handle. virtual int resume_handler (ACE_HANDLE handle); // Resume . virtual int resume_handler (const ACE_Handle_Set &handles); // Resume all in handle set. virtual int resume_handlers (void); // Resume all . virtual int uses_event_associations (void); // Return 1 if we any event associations were made by the reactor // for the handles that it waits on, 0 otherwise. Since the // WFMO_Reactor does use event associations, this function always // return 1. // Timer management. virtual long schedule_timer (ACE_Event_Handler *event_handler, const void *arg, const ACE_Time_Value &delta, const ACE_Time_Value &interval = ACE_Time_Value::zero); // Schedule an that will expire after amount // of time. If it expires then is passed in as the value to // the 's callback method. If // is != to then it is used to // reschedule the automatically. This method // returns a that uniquely identifies the // in an internal list. This can be used to cancel an // before it expires. The cancellation ensures that // are unique up to values of greater than 2 billion // timers. As long as timers don't stay around longer than this // there should be no problems with accidentally deleting the wrong // timer. Returns -1 on failure (which is guaranteed never to be a // valid . virtual int cancel_timer (ACE_Event_Handler *event_handler, int dont_call_handle_close = 1); // Cancel all Event_Handlers that match the address of // . Returns number of handler's cancelled. virtual int cancel_timer (long timer_id, const void **arg = 0, int dont_call_handle_close = 1); // Cancel the single Event_Handler that matches the value // (which was returned from the schedule method). If arg is // non-NULL then it will be set to point to the ``magic cookie'' // argument passed in when the Event_Handler was registered. This // makes it possible to free up the memory and avoid memory leaks. // Returns 1 if cancellation succeeded and 0 if the // wasn't found. // = High-level Event_Handler scheduling operations virtual int schedule_wakeup (ACE_Event_Handler *event_handler, ACE_Reactor_Mask masks_to_be_added); // Add to the 's entry in // WFMO_Reactor. must already have been registered // with WFMO_Reactor. virtual int schedule_wakeup (ACE_HANDLE handle, ACE_Reactor_Mask masks_to_be_added); // Add to the 's entry in WFMO_Reactor. // The Event_Handler associated with must already have been // registered with WFMO_Reactor. virtual int cancel_wakeup (ACE_Event_Handler *event_handler, ACE_Reactor_Mask mask); // This method is identical to the method. virtual int cancel_wakeup (ACE_HANDLE handle, ACE_Reactor_Mask mask); // This method is identical to the method. // = Notification methods. virtual int notify (ACE_Event_Handler * = 0, ACE_Reactor_Mask = ACE_Event_Handler::EXCEPT_MASK, ACE_Time_Value * = 0); // Wakeup one thread if it is currently blocked // in . The indicates how // long to blocking trying to notify the . If // == 0, the caller will block until action is possible, // else will wait until the relative time specified in // elapses). virtual void max_notify_iterations (int); // Set the maximum number of times that the // method will iterate and // dispatch the that are passed in via the // notify queue before breaking out of its // loop. By default, this is set to // -1, which means "iterate until the queue is empty." Setting this // to a value like "1 or 2" will increase "fairness" (and thus // prevent starvation) at the expense of slightly higher dispatching // overhead. virtual int max_notify_iterations (void); // Get the maximum number of times that the // method will iterate and // dispatch the that are passed in via the // notify queue before breaking out of its // loop. virtual int handler (ACE_HANDLE handle, ACE_Reactor_Mask mask, ACE_Event_Handler **event_handler = 0); // Not implemented virtual int handler (int signum, ACE_Event_Handler ** = 0); // Check to see if is associated with a valid Event_Handler // bound to a signal. Return the associated with // this if != 0. virtual int initialized (void); // Returns true if WFMO_Reactor has been successfully initialized, else // false. virtual size_t size (void); // Returns the current size of the WFMO_Reactor's internal // descriptor table. virtual ACE_Lock &lock (void); // Returns a reference to the WFMO_Reactor's internal lock. virtual void wakeup_all_threads (void); // Wake up all threads in WaitForMultipleObjects so that they can // reconsult the handle set virtual int owner (ACE_thread_t new_owner, ACE_thread_t *old_owner = 0); // Transfers ownership of the WFMO_Reactor to the . The // transfer will not complete until all threads are ready (just like // the handle set). virtual int owner (ACE_thread_t *owner); // Return the ID of the "owner" thread. virtual void requeue_position (int); // Not implemented virtual int requeue_position (void); // Not implemented // = Low-level wait_set mask manipulation methods. virtual int mask_ops (ACE_Event_Handler *event_handler, ACE_Reactor_Mask mask, int ops); // Not implemented virtual int mask_ops (ACE_HANDLE handle, ACE_Reactor_Mask mask, int ops); // Not implemented // = Low-level ready_set mask manipulation methods. virtual int ready_ops (ACE_Event_Handler *event_handler, ACE_Reactor_Mask mask, int ops); // Not implemented virtual int ready_ops (ACE_HANDLE handle, ACE_Reactor_Mask, int ops); // Not implemented ACE_ALLOC_HOOK_DECLARE; // Declare the dynamic allocation hooks. void dump (void) const; // Dump the state of an object. protected: virtual int schedule_wakeup_i (ACE_HANDLE handle, ACE_Reactor_Mask masks_to_be_added); // Scheduling workhorse virtual int register_handler_i (ACE_HANDLE event_handle, ACE_HANDLE io_handle, ACE_Event_Handler *event_handler, ACE_Reactor_Mask mask); // Registration workhorse virtual int event_handling (ACE_Time_Value *max_wait_time = 0, int alertable = 0); // Event handling workhorse virtual ACE_thread_t owner_i (void); // Return the ID of the "owner" thread. Does not do any locking. virtual int ok_to_wait (ACE_Time_Value *max_wait_time, int alertable); // Check to see if it is ok to enter ::WaitForMultipleObjects(). virtual int wait_for_multiple_events (ACE_Time_Value *max_wait_time, int alertable); // Wait for timer and I/O events to occur. virtual int dispatch (int wait_status); // Dispatches the timers and I/O handlers. int safe_dispatch (int wait_status); // Protect against structured exceptions caused by user code when // dispatching handles virtual int dispatch_handles (size_t index); // Dispatches any active handles from handles_[] to // handles_[active_handles_] using to poll // through our handle set looking for active handles. virtual int dispatch_handler (int index); // Dispatches a single handler. Returns 0 on success, -1 if the // handler was removed. virtual int simple_dispatch_handler (int index, ACE_HANDLE event_handle); // Dispatches a single handler. Returns 0 on success, -1 if the // handler was removed. virtual int complex_dispatch_handler (int index, ACE_HANDLE event_handle); // Dispatches a single handler. Returns 0 on success, -1 if the // handler was removed. virtual int upcall (ACE_Event_Handler *event_handler, ACE_HANDLE io_handle, ACE_HANDLE event_handle, long interested_events); virtual int calculate_timeout (ACE_Time_Value *time); // Used to caluculate the next timeout virtual int update_state (void); // Update the state of the handler repository virtual int new_owner (void); // Check to see if we have a new owner virtual int change_owner (void); // Set owner to new owner ACE_Sig_Handler *signal_handler_; // Handle signals without requiring global/static variables. int delete_signal_handler_; // Keeps track of whether we should delete the signal handler (if we // didn't create it, then we don't delete it). ACE_Timer_Queue *timer_queue_; // Defined as a pointer to allow overriding by derived classes... int delete_timer_queue_; // Keeps track of whether we should delete the timer queue (if we // didn't create it, then we don't delete it). int delete_handler_rep_; // Keeps track of whether we should delete the handler repository ACE_Process_Mutex lock_; // Synchronization for the ACE_WFMO_Reactor. // // A Process Mutex is used here because of two reasons: // (a) The implementation of ACE_Thread_Mutex uses CriticalSections // CriticalSections are not waitable using ::WaitForMultipleObjects // (b) This is really not a process mutex because it is not // named. No other process can use this mutex. ACE_Lock_Adapter lock_adapter_; // Adapter used to return internal lock to outside world. ACE_WFMO_Reactor_Handler_Repository handler_rep_; // Table that maps to 's. ACE_WFMO_Reactor_Notify notify_handler_; // Used when is called. ACE_Manual_Event ok_to_wait_; // A manual event used to block threads from proceeding into // WaitForMultipleObjects ACE_Manual_Event wakeup_all_threads_; // A manual event is used so that we can wake everyone up (e.g., // when are bounded and unbound from the // handler repository). ACE_Wakeup_All_Threads_Handler wakeup_all_threads_handler_; // Used when is signaled ACE_Auto_Event waiting_to_change_state_; // The changing thread waits on this event, till all threads are not // active anymore size_t active_threads_; // Count of currently active threads ACE_thread_t owner_; // The thread which is "owner" of the WFMO_Reactor. The owner // concept is used because we don't want multiple threads to try to // expire timers. Therefore the "owner" thread is the only one // allowed to expire timers. Also, the owner thread is the only // thread which waits on the notify handle. Note that the ownership // can be transferred. ACE_thread_t new_owner_; // The owner to be of the WFMO_Reactor ACE_thread_t change_state_thread_; // This is the thread which is responsible for the changing the // state of the handle set ACE_HANDLE atomic_wait_array_ [2]; // This is an array of ACE_HANDLEs which keep track of the // and handles int open_for_business_; // This flag is used to keep track of whether we are already closed. private: ACE_WFMO_Reactor (const ACE_WFMO_Reactor &); ACE_WFMO_Reactor &operator = (const ACE_WFMO_Reactor &); // Deny access since member-wise won't work... }; // if we don't have WinSOCK2, we need these defined #if !defined (ACE_HAS_WINSOCK2) || (ACE_HAS_WINSOCK2 == 0) /* * WinSock 2 extension -- bit values and indices for FD_XXX network events */ #define FD_READ_BIT 0 #define FD_WRITE_BIT 1 #define FD_OOB_BIT 2 #define FD_ACCEPT_BIT 3 #define FD_CONNECT_BIT 4 #define FD_CLOSE_BIT 5 #define FD_QOS_BIT 6 #define FD_GROUP_QOS_BIT 7 #define FD_QOS (1 << FD_QOS_BIT) #define FD_GROUP_QOS (1 << FD_GROUP_QOS_BIT) #define FD_MAX_EVENTS 8 #define FD_ALL_EVENTS ((1 << FD_MAX_EVENTS) - 1) #define WSAEVENT HANDLE typedef struct _WSANETWORKEVENTS { long lNetworkEvents; int iErrorCode[FD_MAX_EVENTS]; } WSANETWORKEVENTS, FAR * LPWSANETWORKEVENTS; int WSAEventSelect (SOCKET s, WSAEVENT hEventObject, long lNetworkEvents); int WSAEnumNetworkEvents (SOCKET s, WSAEVENT hEventObject, LPWSANETWORKEVENTS lpNetworkEvents); #endif /* !defined ACE_HAS_WINSOCK2 */ #endif /* ACE_WIN32 */ #if defined (__ACE_INLINE__) #include "ace/WFMO_Reactor.i" #endif /* __ACE_INLINE__ */ #endif /* ACE_WFMO_REACTOR_H */