/* -*- C++ -*- */ //============================================================================= /** * @file TS_Clerk_Handler.h * * @author Prashant Jain */ //============================================================================= #ifndef ACE_TS_CLERK_HANDLER_H #define ACE_TS_CLERK_HANDLER_H #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ #include "ace/SOCK_Connector.h" #include "ace/Svc_Handler.h" #include "ace/Connector.h" #include "ace/MMAP_Memory_Pool.h" #include "ace/Malloc_T.h" #include "ace/Null_Mutex.h" #include "ace/svc_export.h" #include "ace/os_include/os_dirent.h" #include "Time_Request_Reply.h" /** * @class ACE_Time_Info * * @brief A simple struct containing delta time and a sequence number. */ class ACE_Time_Info { public: time_t delta_time_; ACE_UINT32 sequence_num_; }; class ACE_TS_Clerk_Processor; // forward declaration #if defined ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION_EXPORT template class ACE_Svc_Export ACE_Svc_Handler; #endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION_EXPORT */ /** * @class ACE_TS_Clerk_Handler * * @brief The Clerk Handler provides the interface that is used by the * Clerk Processor to send time update requests to all the * servers. It obtains these updates from the servers and passes * the updates to the Clerk Processor * * The Clerk Processor uses send_request() to send a request for * time update to a server. The Clerk Handler internally computes * the round trip delay for the reply to come back. Once it gets * the reply back from the server (handle_input), it adjusts the * system time using the round trip delay estimate and then * passes the delta time by reference back to the Clerk * Processor. */ class ACE_Svc_Export ACE_TS_Clerk_Handler : public ACE_Svc_Handler { public: /// Default constructor. ACE_TS_Clerk_Handler (ACE_TS_Clerk_Processor *processor = 0, ACE_INET_Addr &addr = (ACE_INET_Addr &) ACE_Addr::sap_any); // = Set/get the current state enum State { IDLE = 1, // Prior to initialization. CONNECTING, // During connection establishment. ESTABLISHED, // Connection is established and active. DISCONNECTING, // In the process of disconnecting. FAILED // Connection has failed. }; // = Set/get the current state. State state (); void state (State); // = Set/get the current retry timeout delay. long timeout (); void timeout (long); // = Set/get the maximum retry timeout delay. long max_timeout (); void max_timeout (long); /// Activate this instance of the /// (called by the ). virtual int open (void * = 0); /// Return the handle of the message_fifo_; virtual ACE_HANDLE get_handle () const; /// Called when object is removed from the ACE_Reactor virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE, ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK); /// Receive time update from a server. virtual int handle_input (ACE_HANDLE); /// Restart connection asynchronously when timeout occurs. virtual int handle_timeout (const ACE_Time_Value &tv, const void *arg); /// Get/Set remote addr void remote_addr (ACE_INET_Addr &addr); ACE_INET_Addr &remote_addr (); /// Send request for time update to the server as well as return the /// current time info by reference. int send_request (ACE_UINT32 sequence_num, ACE_Time_Info &time_info); protected: /// Handle SIGPIPE. virtual int handle_signal (int signum, siginfo_t *, ucontext_t *); static void stderr_output (int = 0); enum { MAX_RETRY_TIMEOUT = 300 // 5 minutes is the maximum timeout. }; private: /// Receive a reply from a server containing time update int recv_reply (ACE_Time_Request &reply); /// Reinitiate connection with the server int reinitiate_connection (); /// The current state of the connection State state_; /// Amount of time to wait between reconnection attempts long timeout_; /// Maximum amount of time to wait between reconnection attempts long max_timeout_; /// Remote Addr used for connecting to the server ACE_INET_Addr remote_addr_; /// Instance of Clerk Processor used for re-establishing connections ACE_TS_Clerk_Processor *processor_; /// Time at which request was sent (used to compute round trip delay) time_t start_time_; /// Next sequence number of time request (waiting for this update from /// the server). ACE_UINT32 cur_sequence_num_; /// Record of current delta time and current sequence number ACE_Time_Info time_info_; }; /** * @class ACE_TS_Clerk_Processor * * @brief This class manages all the connections to the servers along * with querying them periodically for time updates. * * The Clerk Processor creates connections to all the servers and * creates an ACE_TS_Clerk_Handler for each connection to handle * the requests and replies. It periodically sends a request for * time update through each of the handlers and uses the replies * for computing a synchronized system time. */ class ACE_TS_Clerk_Processor : public ACE_Connector { public: /// Default constructor ACE_TS_Clerk_Processor (); /// Query servers for time periodically (timeout value) virtual int handle_timeout (const ACE_Time_Value &tv, const void *arg); /// Set up connections to all servers int initiate_connection (ACE_TS_Clerk_Handler *, ACE_Synch_Options &); protected: // = Dynamic linking hooks. /// Called when service is linked. virtual int init (int argc, ACE_TCHAR *argv[]); /// Called when service is unlinked. virtual int fini (); /// Called to determine info about the service. virtual int info (ACE_TCHAR **strp, size_t length) const; // = Scheduling hooks. virtual int suspend (); virtual int resume (); private: /// Parse svc.conf arguments. int parse_args (int argc, ACE_TCHAR *argv[]); /// Allocate entry in shared memory for system time void alloc (); /// Update delta_time using times obtained from all servers int update_time (); /// Allocator (used for reading/writing system time from/to shared memory) typedef ACE_Malloc MALLOC; typedef ACE_Allocator_Adapter ALLOCATOR; ALLOCATOR *shmem_; /// Set of TS_Clerk_Handlers and iterator over the set. typedef ACE_Unbounded_Set HANDLER_SET; typedef ACE_Unbounded_Set_Iterator HANDLER_SET_ITERATOR; HANDLER_SET handler_set_; struct System_Time { time_t *delta_time_; // Diff between system time and local time time_t *last_local_time_; // Last local time }; /// Clerk system time containing pointers to entries in shared memory System_Time system_time_; /// Timer id returned by Reactor long timer_id_; /// Time period for updating system time long timeout_; /// Pool name for backing store ACE_TCHAR poolname_[MAXNAMLEN + 1]; /// Do a blocking/non-blocking connect int blocking_semantics_; /// Sequence number of next expected update from servers ACE_UINT32 cur_sequence_num_; }; ACE_SVC_FACTORY_DECLARE (ACE_TS_Clerk_Processor) #endif /* ACE_TS_CLERK_HANDLER_H */