/* -*- C++ -*- */ // $Id$ /* // ============================================================================ // // = LIBRARY // ACE // // = FILENAME // CLASSIX_Reactor.h // // = AUTHOR(S) // Nokia Telecommunications // // ============================================================================ */ #ifndef ACE_CLASSIX_REACTOR_H #define ACE_CLASSIX_REACTOR_H /* ------------------------------------------------------------------------- */ #include "ace/Timer_Queue.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ #include "ace/Select_Reactor.h" #include "ace/Message_Block.h" #include "ace/CLASSIX/CLASSIX_SAP.h" class ACE_CLASSIX_Select_Reactor; class ACE_Export ACE_CLASSIX_Select_Reactor_Notify : public ACE_Reactor_Notify { // = TITLE // Unblock the from its event loop. // // = DESCRIPTION // This replaces class. // Instead of using pipe, this class uses an Chorus IPC port to // trigger the unblock event. // public: // = Initialization and termination methods. ACE_CLASSIX_Select_Reactor_Notify(void); ~ACE_CLASSIX_Select_Reactor_Notify(void); virtual int open (ACE_Reactor_Impl *, ACE_Timer_Queue * = 0, int = 0 /* dusable_notify_pip */); // Enables the notification port and register it with the reactor virtual int close (void); // Disables the notification port int dispatch_notifications (int &number_of_active_handles, const ACE_Handle_Set &rd_mask); // Handles pending threads (if any) that are waiting to unblock the // Select_Reactor. ssize_t 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 // select()/poll(). Pass over both the *and* the // to allow the caller to dictate which // method the will invoke. 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 int handle_input (ACE_HANDLE handle); // Called back by the Select_Reactor when a thread wants to unblock us. virtual void max_notify_iterations (int); // Set the maximum number of times that the // method will iterate // Always 1. virtual int max_notify_iterations (void); // Get the maximum number of times that the // method will iterate. // Always 1 void dump (void) const; // Dump the state of an object. ACE_ALLOC_HOOK_DECLARE; // Declare the dynamic allocation hooks. private: ACE_CLASSIX_Select_Reactor *select_reactor_; // Keep a back pointer to the . If this value // if NULL then the has been initialized with // . ACE_CLASSIX_Port_Core notification_port_; // CLASSIX' IPC port ACE_CLASSIX_SAP notification_sap_; // The HANDLE that the Select_Reactor is listening on and // the HANDLE that threads wanting the attention of the // Select_Reactor will write t are the same. // It can be seen that the notification port is implicitly connected to the // port from where the notification is written. In many cases, it will be // the actor's default port. }; class ACE_CLASSIX_Select_Reactor : public ACE_Select_Reactor // = TITLE // Implementing a Reactor for monitoring incoming data // // = DESCRIPTION // This class redefines the wait_for_events() method of // class. // // The wait_for_events() method uses ipcReceive() to monitor // all ENABLED ports for incoming messages. The ipcReceive() is // set up such that it will find out the size of the message but will // not read the message. The Chorus OS provides an ipcGetData() // to read the message that has just been detected on the same // thread. // Once a message is detected on a particular // port, the reactor will invoke the port handler's // handle_input() method on the same thread. It is important that // handle_input() shall immediately retrieve(use ipcGetData()) // the message on the same // thread and it shall not hold up this thread in the handle_input() // routine for too long. This will allow the Reactor to respond to // events more quickly. // // = NOTE // Since chorus does not allow ipcReceive to monitor a subset of // ENABLED ports. One cannot have two ACE_CLASSIX_Select_Reactors // in one actor. // { public: // = CURRENT MESSAGE // The following message should be called in the handler's // handle_input() routine. // The handle_input() routine should not hold the reactor for too long. virtual int current_info(ACE_HANDLE /* port */, size_t& /* msg size */); // Retruns the current messageage to the caleer if the supplied // handle id is the same as the // Returns 0, if constains the size of the message // that the handler shall read. // Returns -1, if the caller is not the expected handler. protected: // = INITIALIZATION ACE_CLASSIX_Select_Reactor (ACE_Timer_Queue * = 0); // Initializes with the handler // repository of the default size. ACE_CLASSIX_Select_Reactor (size_t size, int restart = 0, ACE_Timer_Queue * = 0); // Initializes with the handler repository of // size . // multiplexer virtual int wait_for_multiple_events (ACE_Select_Reactor_Handle_Set &, ACE_Time_Value *); // Wait for events to occur. virtual int set_current_info_(ACE_HANDLE /* handle */, size_t /* size of data */); // record the handler and the size of the message that the handler shall // read next. // ACE_Recursive_Thread_Mutex lock_current_; // lock for data relating to the current message. // use token lock size_t current_msg_size_; // size of the message that has just been detected. ACE_HANDLE current_handle_; // handler id of the current address. friend class ACE_CLASSIX_Select_Reactor_Notify; friend class ACE_CLASSIX_OS; // for constructors private: int handle_error_(int /* port handle */); // Takes corrective action when errors occur. int check_handles_(int /* port handle */); // Makes sure the handler is valid. ACE_CLASSIX_Select_Reactor(ACE_CLASSIX_Select_Reactor const&); ACE_CLASSIX_Select_Reactor const& operator=(ACE_CLASSIX_Select_Reactor const&); }; /* ------------------------------------------------------------------------- */ #if defined (__ACE_INLINE__) #include "ace/CLASSIX/CLASSIX_Select_Reactor.i" #endif /* __ACE_INLINE__ */ #endif /* ACE_CLASSIX_REACTOR_H */