// -*- C++ -*- //============================================================================= /** * @file Remote_Tokens.h * * @author Douglas C. Schmidt (d.schmidt@vanderbilt.edu) * @author Tim Harrison (harrison@cs.wustl.edu) */ //============================================================================= #ifndef ACE_REMOTE_MUTEX_H #define ACE_REMOTE_MUTEX_H #include /**/ "ace/pre.h" #include "ace/INET_Addr.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ #include "ace/SOCK_Connector.h" #include "ace/SOCK_Stream.h" #include "ace/Synch_Options.h" #include "ace/Local_Tokens.h" #include "ace/Token_Request_Reply.h" #if defined (ACE_HAS_TOKENS_LIBRARY) ACE_BEGIN_VERSIONED_NAMESPACE_DECL /** * @class ACE_Remote_Token_Proxy * * @brief Proxy for acquiring, renewing, and releasing a distributed * synchronization token. * * The Remote_Token_Proxy class implements the mechanisms for * distributed token operations. It is similar to the * ACE_Token_Proxy. * @todo * Distributed sleep_hooks have not been implemented. * is not implemented. */ class ACE_Export ACE_Remote_Token_Proxy : public ACE_Token_Proxy { public: /// Null construction. ACE_Remote_Token_Proxy (); /// Death. virtual ~ACE_Remote_Token_Proxy (); /** * Same as Token_Proxy. @a name is the string uniquely identifying * the token. @a ignore_deadlock can be 1 to disable deadlock * notifications. @a debug prints debug messages. */ int open (const ACE_TCHAR *name, int ignore_deadlock = 0, int debug = 0); /** * Open a connection with the token server. This only need be used * when the user wishes to explicitly open a connection to check if * the server exists. Connections are stored in the * ACE_Token_Connections singleton as thread-specific data. That * is, every thread has only one connection that is used for all * remote tokens. */ int initiate_connection (); /** * Acquire the distributed token. If notify is specified and the * token is already held, the owner is notified. options contains * the timeout value for the acquire call. The timer is kept at the * token server. Asynchronous operations are not supported. * Returns 0 on success, -1 on failure with @c errno == problem. */ virtual int acquire (int notify = 0, void (*sleep_hook)(void *) = 0, ACE_Synch_Options &options = ACE_Synch_Options::synch); /** * Try to acquire the distributed token. If the token is already * held, the call returns without queuing the caller as a waiter. * Returns 0 on success (the token was acquired), and -1 with * EWOULDBLOCK if the token was already held. */ virtual int tryacquire (void (*sleep_hook)(void *) = 0); /** * Renew the token by offering to release it if there are any other * waiters, otherwise get the token back immediately. This renew * has the same semantics as ACE_Local_Mutex release. It is * semantically equivalent to release() followed by acquire(), but * it is faster. options contains the timeout value used if renew * blocks. As with acquire, the timer is maintained at the token * server. If there are waiters and requeue_position == -1, the * caller is queued at the rear of the waiter list. Otherwise, * requeue_position specifies the number of waiters to "let by" * before reacquiring the token (effectively, the position in the * waiter list.) */ virtual int renew (int requeue_position = 0, ACE_Synch_Options &options = ACE_Synch_Options::synch); /** * Release the distributed token. Similar to ACE_Local_Mutex, if the * caller is not the owner, it is removed from the waiter list (if * applicable.) Returns 0 on success, -1 on failure with @c errno == * problem. */ virtual int release (ACE_Synch_Options &options = ACE_Synch_Options::synch); /// Become interface compliant for our guards. This has no /// functionality. virtual int remove (ACE_Synch_Options &options = ACE_Synch_Options::synch); /// Override the default to do nothing. virtual void token_acquired (ACE_TPQ_Entry *); /// The client id of the current token holder virtual const ACE_TCHAR* owner_id (); /** * Sets the server address for all instances of ACE_Remote_Token_Proxy * If this isn't called, the environment variable TOKEN_SERVER is * checked for the server address. If that is not specified, all * ACE_Remote_** operations will fail. */ static void set_server_address (const ACE_INET_Addr &server_address); /// Dump the state of the class. void dump () const; protected: /// If shadows report deadlock, go remote anyway int ignore_shadow_deadlock_; /// Perform the request and wait for the reply. int request_reply (ACE_Token_Request &request, ACE_Synch_Options &options); }; /** * @class ACE_Remote_Mutex * * @brief Proxy for acquiring, renewing, and releasing a distributed * mutex. * * This is the remote equivalent to ACE_Local_Mutex. The * Remote_Mutex class offers methods for acquiring, renewing, and * releasing a distributed synchronization mutex. Similar to * ACE_Local_Mutex, ACE_Remote_Token_Proxy offers recursive * acquisition, FIFO waiter ordering, and deadlock detection. It * depends on the Token Server for its distributed synchronization * semantics. */ class ACE_Export ACE_Remote_Mutex : public ACE_Remote_Token_Proxy { public: /// Null creation. Remote_Token_Proxy::open must be called. ACE_Remote_Mutex (); /// Calls Remote_Token_Proxy::open for you. ACE_Remote_Mutex (const ACE_TCHAR *token_name, int ignore_deadlock = 0, int debug = 0); /// Dump the state of the class. void dump () const; /// Return deep copy. virtual ACE_Token_Proxy *clone () const; protected: /// Make the correct type of ACE_Tokens. /// This is called by the ACE_Token_Manager. virtual ACE_Tokens *create_token (const ACE_TCHAR *name); }; /** * @class ACE_Remote_RLock * * @brief Proxy for acquiring, renewing, and releasing a distributed * readers lock. * * This is the remote equivalent to ACE_Local_RLock. Multiple * readers can hold the lock simultaneously when no writers have * the lock. Alternatively, when a writer holds the lock, no other * participants (readers or writers) may hold the lock. * ACE_Remote_RLock depends on the ACE Token Server for its * distributed synchronization semantics. */ class ACE_Export ACE_Remote_RLock : public ACE_Remote_Token_Proxy { public: ACE_Remote_RLock (); ACE_Remote_RLock (const ACE_TCHAR *token_name, int ignore_deadlock = 0, int debug = 0); ACE_Remote_RLock (const ACE_Remote_RLock &mutex); /// Dump the state of the class. void dump () const; /// Returns ACE_RW_Token::RLOCK; virtual int type () const; /// Return deep copy. virtual ACE_Token_Proxy *clone () const; protected: /// Make the correct type of ACE_Tokens. This is called by the Token /// Manager. virtual ACE_Tokens *create_token (const ACE_TCHAR *name); }; /** * @class ACE_Remote_WLock * * @brief Proxy for acquiring, renewing, and releasing a distributed * writers lock. * * Shields applications from details of interacting with the * ACE_Token_Server. The token_name_ is just the string that the * Token Server uses to identify the token. The client_id_ (also * used by the Token Server,) identifies the owner of the token and * is used for deadlock detection. */ class ACE_Export ACE_Remote_WLock : public ACE_Remote_Token_Proxy { public: ACE_Remote_WLock (); ACE_Remote_WLock (const ACE_TCHAR *token_name, int ignore_deadlock = 0, int debug = 0); ACE_Remote_WLock (const ACE_Remote_WLock &mutex); /// Dump the state of the class. void dump () const; /// Returns ACE_RW_Token::WLOCK; virtual int type () const; /// Return deep copy. virtual ACE_Token_Proxy *clone () const; protected: /// Make the correct type of ACE_Tokens. This is called by the Token /// Manager. virtual ACE_Tokens *create_token (const ACE_TCHAR *name); }; /** * @class ACE_TSS_Connection * * @brief Class for providing a connection per thread. * * ACE_TSS_Connection provides a single access point for all * threads to access thread-specific connections. This prevents * resource-sharing problems such as thread serialization. */ class ACE_Export ACE_TSS_Connection : public ACE_TSS { public: // Necessary to make some compilers work... ACE_TSS_Connection (); ~ACE_TSS_Connection (); /// Retrieve the thread's connection ACE_SOCK_Stream *get_connection (); /// Factory Method that creates a new SOCK Stream. virtual ACE_SOCK_Stream *make_TSS_TYPE () const; /// Inheritance and operator overloading don't mix. Redefine this /// from ACE_TSS so that we can use it. operator ACE_SOCK_Stream *(); /// Set the server address. static void set_server_address (const ACE_INET_Addr &server_address); /// Dump the state of the class. void dump () const; protected: /// The address of the Token Server used by all instances of /// Token_Proxy. static ACE_INET_Addr server_address_; private: ACE_TSS_Connection (const ACE_TSS_Connection &) = delete; void operator= (const ACE_TSS_Connection &) = delete; }; ACE_END_VERSIONED_NAMESPACE_DECL #endif /* ACE_HAS_TOKENS_LIBRARY */ #if defined (__ACE_INLINE__) #include "ace/Remote_Tokens.inl" #endif /* __ACE_INLINE__ */ #include /**/ "ace/post.h" #endif /* ACE_REMOTE_TOKEN_H */