// -*- C++ -*- //============================================================================= /** * @file Proactor.h * * @author Irfan Pyarali * @author Tim Harrison * @author Alexander Babu Arulanthu * @author Alexander Libman */ //============================================================================= #ifndef ACE_PROACTOR_H #define ACE_PROACTOR_H #include /**/ "ace/pre.h" #include /**/ "ace/config-all.h" #include /**/ "ace/ACE_export.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) #pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ #if defined (ACE_HAS_WIN32_OVERLAPPED_IO) || defined (ACE_HAS_AIO_CALLS) // This only works on Win32 platforms and on Unix platforms supporting // POSIX aio calls. # include "ace/Asynch_IO.h" # include "ace/Asynch_IO_Impl.h" # include "ace/Thread_Manager.h" # include "ace/Timer_Queue.h" # include "ace/Timer_List.h" # include "ace/Timer_Heap.h" # include "ace/Timer_Wheel.h" ACE_BEGIN_VERSIONED_NAMESPACE_DECL // Forward declarations. class ACE_Proactor_Impl; class ACE_Proactor_Timer_Handler; /// Type def for the timer queue. typedef ACE_Abstract_Timer_Queue ACE_Proactor_Timer_Queue; /** * @class ACE_Proactor_Handle_Timeout_Upcall * * @brief Functor for ACE_Timer_Queue. * * This class implements the functor required by the Timer * Queue to call on ACE_Handlers. */ class ACE_Export ACE_Proactor_Handle_Timeout_Upcall { /// The main Proactor class has special permissions. friend class ACE_Proactor; public: /// Constructor. ACE_Proactor_Handle_Timeout_Upcall (); /// This method is called when a timer is registered. int registration (ACE_Proactor_Timer_Queue &timer_queue, ACE_Handler *handler, const void *arg); /// This method is called before the timer expires. int preinvoke (ACE_Proactor_Timer_Queue &timer_queue, ACE_Handler *handler, const void *arg, int recurring_timer, const ACE_Time_Value &cur_time, const void *&upcall_act); /// This method is called when the timer expires. int timeout (ACE_Proactor_Timer_Queue &timer_queue, ACE_Handler *handler, const void *arg, int recurring_timer, const ACE_Time_Value &cur_time); /// This method is called after the timer expires. int postinvoke (ACE_Proactor_Timer_Queue &timer_queue, ACE_Handler *handler, const void *arg, int recurring_timer, const ACE_Time_Value &cur_time, const void *upcall_act); /// This method is called when a handler is canceled. int cancel_type (ACE_Proactor_Timer_Queue &timer_queue, ACE_Handler *handler, int dont_call_handle_close, int &requires_reference_counting); /// This method is called when a timer is canceled. int cancel_timer (ACE_Proactor_Timer_Queue &timer_queue, ACE_Handler *handler, int dont_call_handle_close, int requires_reference_counting); /// This method is called when the timer queue is destroyed and the /// timer is still contained in it. int deletion (ACE_Proactor_Timer_Queue &timer_queue, ACE_Handler *handler, const void *arg); protected: /// Set the proactor. This will fail, if one is already set! int proactor (ACE_Proactor &proactor); /// Handle to the proactor. This is needed for posting a timer result /// to the Proactor's completion queue. ACE_Proactor *proactor_; }; /** * @class ACE_Proactor * * @brief A manager for asynchronous event demultiplexing. * * See the Proactor pattern description at * http://www.dre.vanderbilt.edu/~schmidt/PDF/proactor.pdf for more * details. */ class ACE_Export ACE_Proactor { // = Here are the private typedefs that the ACE_Proactor uses. typedef ACE_Timer_Queue_Iterator_T TIMER_QUEUE_ITERATOR; typedef ACE_Timer_List_T TIMER_LIST; typedef ACE_Timer_List_Iterator_T TIMER_LIST_ITERATOR; typedef ACE_Timer_Heap_T TIMER_HEAP; typedef ACE_Timer_Heap_Iterator_T TIMER_HEAP_ITERATOR; typedef ACE_Timer_Wheel_T TIMER_WHEEL; typedef ACE_Timer_Wheel_Iterator_T TIMER_WHEEL_ITERATOR; // = Friendship. /// Timer handler runs a thread and manages the timers, on behalf of /// the Proactor. friend class ACE_Proactor_Timer_Handler; public: /** * Constructor. If @a implementation is 0, the correct implementation * object will be created. @a delete_implementation flag determines * whether the implementation object should be deleted by the * Proactor or not. If @a tq is 0, a new TIMER_QUEUE is created. */ ACE_Proactor (ACE_Proactor_Impl *implementation = 0, bool delete_implementation = false, ACE_Proactor_Timer_Queue *tq = 0); /// Destruction. ~ACE_Proactor (); /// Get pointer to a process-wide ACE_Proactor. @a threads should /// be part of another method. static ACE_Proactor *instance (size_t threads = 0); /// Set pointer to a process-wide ACE_Proactor and return existing /// pointer. static ACE_Proactor *instance (ACE_Proactor * proactor, bool delete_proactor = false); /// Delete the dynamically allocated Singleton. static void close_singleton (); /// Cleanup method, used by the ACE_Object_Manager to destroy the /// singleton. static void cleanup (void *instance, void *arg); /// Name of dll in which the singleton instance lives. static const ACE_TCHAR *dll_name (); /// Name of component--ACE_Proactor in this case. static const ACE_TCHAR *name (); // = Proactor event loop management methods. /// Run the event loop until the method /// returns -1 or the method is invoked. static int run_event_loop (); /** * Run the event loop until the method * returns -1, the method is invoked, or the * ACE_Time_Value expires, in which case 0 is returned. */ static int run_event_loop (ACE_Time_Value &tv); /** * Instruct the to terminate its event * loop. * This method wakes up all the threads blocked on waiting for * completions and end the event loop. */ static int end_event_loop (); /** * Resets the static so that the * method can be restarted. */ static int reset_event_loop (); /** * The singleton proactor is used by the ACE_Service_Config. * Therefore, we must check for the reconfiguration request and * handle it after handling an event. */ static int check_reconfiguration (ACE_Proactor *); /// Report if the event loop is finished. static int event_loop_done (); /// Close the associated @c ACE_Proactor_Impl implementation object. /** * If @arg delete_implementation was specified to the @c open() method, * the implementation object is also deleted. */ int close (); /** * You can add a hook to various run_event methods and the hook will * be called after handling every proactor event. If this function * returns 0, proactor_run_event_loop will check for the return value of * handle_events. If it is -1, the the proactor_run_event_loop will return * (pre-maturely.) */ typedef int (*PROACTOR_EVENT_HOOK)(ACE_Proactor *); // These methods work with an instance of a proactor. /** * Run the event loop until the * * method returns -1 or the method is invoked. */ int proactor_run_event_loop (PROACTOR_EVENT_HOOK = 0); /** * Run the event loop until the * method returns -1, the * method is invoked, * or the ACE_Time_Value * expires, in which case a 0 is returned. */ int proactor_run_event_loop (ACE_Time_Value &tv, PROACTOR_EVENT_HOOK = 0); /** * Instruct the ACE_Proactor to terminate its event loop * and notifies the ACE_Proactor so that it can wake up * and close down gracefully. */ int proactor_end_event_loop (); /// Report if the ACE_Proactor event loop is finished. int proactor_event_loop_done (); /// Resets the static so that the /// method can be restarted. int proactor_reset_event_loop (); /// This method adds the @a handle to the I/O completion port. This /// function is a no-op function for Unix systems and returns 0; int register_handle (ACE_HANDLE handle, const void *completion_key); // = Timer management. /** * Schedule a @a handler that will expire after