/* -*- C++ -*- */ //============================================================================= /** * @file Token_Manager.h * * $Id$ * * @author Tim Harrison (harrison@cs.wustl.edu) */ //============================================================================= #ifndef ACE_TOKEN_MANAGER_H #define ACE_TOKEN_MANAGER_H #include "ace/pre.h" #include "ace/Synch.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ #include "ace/Map_Manager.h" #include "ace/Local_Tokens.h" 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 (void); virtual ~ACE_Token_Manager (void); // Set/get a pointer to token manager singleton. static ACE_Token_Manager *instance (void); 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_. uniquely * id's the token name. */ void get_token (ACE_Token_Proxy *, const ACE_TCHAR *token_name); /** * 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 (void); /// Dump the state of the class. void dump (void) const; /// Turn debug mode on/off. void debug (int d); private: /// Whether to print debug messages or not. int 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; /// Allows iterations through collection_ typedef ACE_Map_Iterator COLLECTION_ITERATOR; /// Allows iterations through collection_ typedef ACE_Map_Entry COLLECTION_ENTRY; /// COLLECTION maintains a mapping from token names to ACE_Tokens*. COLLECTION collection_; }; #if defined (__ACE_INLINE__) #include "ace/Token_Manager.i" #endif /* __ACE_INLINE__ */ #include "ace/post.h" #endif /* ACE_TOKEN_MANAGER_H */