/* -*- C++ -*- */ // $Id$ // ============================================================================ // // = LIBRARY // ace // // = FILENAME // Select_Reactor_T.h // // = AUTHOR // Doug Schmidt // // ============================================================================ #ifndef ACE_SELECT_REACTOR_T_H #define ACE_SELECT_REACTOR_T_H #include "ace/pre.h" #include "ace/Select_Reactor_Base.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ template class ACE_Select_Reactor_Token_T : public ACE_SELECT_REACTOR_MUTEX { // = TITLE // Used as a synchronization mechanism to coordinate concurrent // access to a Select_Reactor object. // // = DESCRIPTION // This class is used to make the // thread-safe. By default, the thread that runs the // loop holds the token, even when it is blocked // in the call and gets // ``re-acquired'' as soon as the // there would be a good chance that the could have // been modified while the . Thus, it is not critical to change the // . The implementation of the mechanism // provided by the enables the // default owner to be the thread that executes the dispatch // loop. public: ACE_Select_Reactor_Token_T (ACE_Select_Reactor_Impl &r); ACE_Select_Reactor_Token_T (void); virtual ~ACE_Select_Reactor_Token_T (void); virtual void sleep_hook (void); // Called just before the ACE_Event_Handler goes to sleep. ACE_Select_Reactor_Impl &select_reactor (void); void select_reactor (ACE_Select_Reactor_Impl &); // Set/Get methods virtual void dump (void) const; // Dump the state of an object. ACE_ALLOC_HOOK_DECLARE; // Declare the dynamic allocation hooks. private: ACE_Select_Reactor_Impl *select_reactor_; }; template class ACE_Select_Reactor_T : public ACE_Select_Reactor_Impl { // = TITLE // An object oriented event demultiplexor and event handler // dispatcher. // // = DESCRIPTION // The is an object-oriented event // demultiplexor and event handler dispatcher. The sources of // events that the waits for and dispatches // includes I/O events, signals, and timer events. All public // methods acquire the main lock and // call down to private or protected methods, which assume that // the lock is held and so therefore don't (re)acquire the lock. public: // = Initialization and termination methods. ACE_Select_Reactor_T (ACE_Sig_Handler * = 0, ACE_Timer_Queue * = 0, int disable_notify_pipe = 0, ACE_Reactor_Notify *notify = 0, int mask_signals = 1); // Initialize with the default size. ACE_Select_Reactor_T (size_t size, int restart = 0, ACE_Sig_Handler * = 0, ACE_Timer_Queue * = 0, int disable_notify_pipe = 0, ACE_Reactor_Notify *notify = 0, int mask_signals = 1); // Initialize with size . virtual int open (size_t max_number_of_handles = DEFAULT_SIZE, int restart = 0, ACE_Sig_Handler * = 0, ACE_Timer_Queue * = 0, int disable_notify_pipe = 0, ACE_Reactor_Notify * = 0); // Initialize the to manage // . If is non-0 then the // 's method will be restarted // automatically when occurs. If or // are non-0 they are used as the signal handler and // timer queue, respectively. If is non-0 the // notification pipe is not created, thereby saving two I/O handles. virtual int current_info (ACE_HANDLE, size_t & /* size */); // Returns -1 (not used in this implementation); 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 select_reactor and release all of its resources. virtual ~ACE_Select_Reactor_T (void); // Close down the select_reactor and release all of its resources. // = Event loop drivers. virtual int work_pending (const ACE_Time_Value &max_wait_time = ACE_Time_Value::zero); // Returns non-zero if there are I/O events "ready" for dispatching, // but does not actually dispatch the event handlers. By default, // don't block while checking this, i.e., "poll". 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 that blocks for 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. // // Returns the total number of I/O and Timer s // that were dispatched, 0 if the elapsed without // dispatching any handlers, or -1 if something goes wrong. // // Current is identical to // . 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. // // Current is identical to // . // = Event handling control. virtual int deactivated (void); // Return the status of Reactor. If this function returns 0, the reactor is // actively handling events. If it returns non-zero, and // return -1 immediately. virtual void deactivate (int do_stop); // Control whether the Reactor will handle any more incoming events or not. // If == 1, the Reactor will be disabled. By default, a reactor // is in active state and can be deactivated/reactived as wish. // = Register and remove s. virtual int register_handler (ACE_Event_Handler *eh, ACE_Reactor_Mask mask); // Register a with a particular . Note that the // will call to // extract the underlying I/O handle. virtual int register_handler (ACE_HANDLE handle, ACE_Event_Handler *eh, ACE_Reactor_Mask mask); // Register a with a particular . Note that since the // is given the Select_Reactor will *not* call // to extract the underlying I/O // handle. #if defined (ACE_WIN32) // Originally this interface was available for all platforms, but // because ACE_HANDLE is an int on non-Win32 platforms, compilers // are not able to tell the difference between // register_handler(ACE_Event_Handler*,ACE_Reactor_Mask) and // register_handler(ACE_Event_Handler*,ACE_HANDLE). Therefore, we // have restricted this method to Win32 only. virtual int register_handler (ACE_Event_Handler *event_handler, ACE_HANDLE event_handle = ACE_INVALID_HANDLE); // Not implemented. #endif /* ACE_WIN32 */ virtual int register_handler (ACE_HANDLE event_handle, ACE_HANDLE io_handle, ACE_Event_Handler *event_handler, ACE_Reactor_Mask mask); // Not implemented. virtual int register_handler (const ACE_Handle_Set &handles, ACE_Event_Handler *eh, 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 *eh, ACE_Reactor_Mask mask); // Removes the binding of from the Select_Reactor. If // there are no more bindings for this then it is removed from // the Select_Reactor. Note that the Select_Reactor will call // to extract the underlying I/O // handle. virtual int remove_handler (ACE_HANDLE handle, ACE_Reactor_Mask); // Removes the bind of whose handle is // from the Select_Reactor. If there are no more bindings // for this then it is removed from the Select_Reactor. 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 handlers then they are removed from the Select_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 *eh); // Temporarily suspend the associated with . virtual int suspend_handler (ACE_HANDLE handle); // Temporarily suspend the associated with . virtual int suspend_handler (const ACE_Handle_Set &handles); // Suspend all in handle set temporarily. virtual int suspend_handlers (void); // Suspend all the in the Select_Reactor. virtual int resume_handler (ACE_Event_Handler *eh); // Resume a temporarily suspend associated with // . virtual int resume_handler (ACE_HANDLE handle); // Resume a temporarily suspended associated with // . virtual int resume_handler (const ACE_Handle_Set &handles); // Resume all in handle set. virtual int resume_handlers (void); // Resume all the in the Select_Reactor. 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 // Select_Reactor does not do any event associations, this function // always return 0. // = Timer management. virtual long schedule_timer (ACE_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, which is specified as relative time to the current // . 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, which is also // specified using relative time. 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 reset_timer_interval (long timer_id, const ACE_Time_Value &interval); // Resets the interval of the timer represented by to // , which is specified in relative time to the current // . If is equal to // , the timer will become a non-rescheduling // timer. Returns 0 if successful, -1 if not. virtual int cancel_timer (ACE_Event_Handler *event_handler, int dont_call_handle_close = 1); // Cancel all that match the address of // . If is 0 then the // method of will be invoked. // 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 that matches the // value (which was returned from the method). If arg is // non-NULL then it will be set to point to the ``magic cookie'' // argument passed in when the was registered. This // makes it possible to free up the memory and avoid memory leaks. // If is 0 then the method // of will be invoked. 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 *eh, ACE_Reactor_Mask mask); // ADD the dispatch MASK "bit" bound with the and the . virtual int schedule_wakeup (ACE_HANDLE handle, ACE_Reactor_Mask mask); // ADD the dispatch MASK "bit" bound with the and the . virtual int cancel_wakeup (ACE_Event_Handler *eh, ACE_Reactor_Mask mask); // CLR the dispatch MASK "bit" bound with the and the . virtual int cancel_wakeup (ACE_HANDLE handle, ACE_Reactor_Mask mask); // CLR the dispatch MASK "bit" bound with the and the . // = Notification methods. virtual int notify (ACE_Event_Handler * = 0, ACE_Reactor_Mask = ACE_Event_Handler::EXCEPT_MASK, ACE_Time_Value * = 0); // Called by a thread when it wants to unblock the Select_Reactor. // This wakeups the if currently blocked in //