// -*- C++ -*- //============================================================================= /** * @file Token_Manager.h * * @author Tim Harrison (harrison@cs.wustl.edu) */ //============================================================================= #ifndef ACE_TOKEN_MANAGER_H #define ACE_TOKEN_MANAGER_H #include /**/ "ace/pre.h" #include /**/ "ace/config-all.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ #include "ace/Local_Tokens.h" #if defined (ACE_HAS_TOKENS_LIBRARY) #include "ace/Null_Mutex.h" #include "ace/Map_Manager.h" ACE_BEGIN_VERSIONED_NAMESPACE_DECL class ACE_Local_Mutex; class ACE_Mutex_Token; /** * @class ACE_Token_Manager * * @brief Manages all tokens in a process space. * * Factory: Proxies use the token manager to obtain token * references. This allows multiple proxies to reference the same * logical token. * Deadlock detection: Tokens use the manager to check for * deadlock situations during acquires. */ class ACE_Export ACE_Token_Manager : public ACE_Cleanup { // To add a new type of token (e.g. semaphore), do the following // steps: 1. Create a new derivation of ACE_Token. This class // defines the semantics of the new Token. 2. Create a // derivation of ACE_Token_Manager. You will only need to // redefine make_mutex. public: ACE_Token_Manager (); virtual ~ACE_Token_Manager (); /// Get the pointer to token manager singleton. static ACE_Token_Manager *instance (); /// Set the pointer to token manager singleton. void instance (ACE_Token_Manager *); /** * The Token manager uses ACE_Token_Proxy::token_id_ to look for * an existing token. If none is found, the Token Manager calls * ACE_Token_Proxy::create_token to create a new one. When * finished, sets ACE_Token_Proxy::token_. @a token_name uniquely * id's the token name. */ void get_token (ACE_Token_Proxy *, const ACE_TCHAR *token_name); /** * Check whether acquire will cause deadlock or not. * returns 1 if the acquire will _not_ cause deadlock. * returns 0 if the acquire _will_ cause deadlock. * This method ignores recursive acquisition. That is, it will not * report deadlock if the client holding the token requests the * token again. Thus, it assumes recursive mutexes. */ int check_deadlock (ACE_Token_Proxy *proxy); int check_deadlock (ACE_Tokens *token, ACE_Token_Proxy *proxy); /// Notify the token manager that a token has been released. If as a /// result, there is no owner of the token, the token is deleted. void release_token (ACE_Tokens *&token); /** * This is to allow Tokens to perform atomic transactions. The * typical usage is to acquire this mutex, check for a safe_acquire, * perform some queueing (if need be) and then release the lock. * This is necessary since safe_acquire is implemented in terms of * the Token queues. */ ACE_TOKEN_CONST::MUTEX &mutex (); /// Dump the state of the class. void dump () const; /// Turn debug mode on/off. void debug (bool d); private: /// Whether to print debug messages or not. bool debug_; /// pointer to singleton token manager. static ACE_Token_Manager *token_manager_; /// Return the token that the given client_id is waiting for, if any ACE_Tokens *token_waiting_for (const ACE_TCHAR *client_id); /// ACE_Mutex_Token used to lock internal data structures. ACE_TOKEN_CONST::MUTEX lock_; /// This may be changed to a template type. typedef ACE_Token_Name TOKEN_NAME; /// COLLECTION maintains a mapping from token names to ACE_Tokens* typedef ACE_Map_Manager COLLECTION; /// COLLECTION maintains a mapping from token names to ACE_Tokens*. COLLECTION collection_; }; ACE_END_VERSIONED_NAMESPACE_DECL #if defined (__ACE_INLINE__) #include "ace/Token_Manager.inl" #endif /* __ACE_INLINE__ */ #endif /* ACE_HAS_TOKENS_LIBRARY */ #include /**/ "ace/post.h" #endif /* ACE_TOKEN_MANAGER_H */