NAME
ACE_Token_Manager -
Manages all tokens in a process space.
SYNOPSIS
#include <ace/Token_Manager>
class ACE_Token_Manager
{
public:
ACE_Token_Manager (void);
~ACE_Token_Manager (void);
static ACE_Token_Manager *instance (void);
void instance (ACE_Token_Manager *);
void get_token (ACE_Token_Proxy *, const char *token_name);
int check_deadlock (ACE_Token_Proxy *proxy);
int check_deadlock (ACE_Tokens *token, ACE_Token_Proxy *proxy);
void release_token (ACE_Tokens *&token);
ACE_TOKEN_CONST::MUTEX &mutex (void);
void dump (void) const;
void debug (int d);
private:
int debug_;
static ACE_Token_Manager *token_manager_;
static ACE_TOKEN_CONST::MUTEX creation_lock_;
ACE_Tokens *token_waiting_for (const char *client_id);
ACE_TOKEN_CONST::MUTEX lock_;
typedef ACE_Token_Name TOKEN_NAME;
typedef ACE_Map_Manager<TOKEN_NAME, ACE_Tokens *, ACE_Null_Mutex> COLLECTION;
typedef ACE_Map_Iterator<TOKEN_NAME, ACE_Tokens *, ACE_Null_Mutex> COLLECTION_ITERATOR;
typedef ACE_Map_Entry<TOKEN_NAME, ACE_Tokens *> COLLECTION_ENTRY;
COLLECTION collection_;
};
DESCRIPTION
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.
PUBLIC MEMBERS
ACE_Token_Manager (void);
~ACE_Token_Manager (void);
static ACE_Token_Manager *instance (void);
void instance (ACE_Token_Manager *);
void get_token (ACE_Token_Proxy *, const char *token_name);
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_. token_name uniquely
id's the token name.
int check_deadlock (ACE_Token_Proxy *proxy);
int check_deadlock (ACE_Tokens *token, ACE_Token_Proxy *proxy);
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.
void release_token (ACE_Tokens *&token);
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.
ACE_TOKEN_CONST::MUTEX &mutex (void);
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.
void dump (void) const;
Dump the state of the class.
void debug (int d);
PRIVATE MEMBERS
int debug_;
Wether to print debug messages or not.
static ACE_Token_Manager *token_manager_;
pointer to singleton token manager.
static ACE_TOKEN_CONST::MUTEX creation_lock_;
make sure that token_manager_ is created atomically (only once!)
ACE_Tokens *token_waiting_for (const char *client_id);
return the token that the given client_id is waiting for, if any
ACE_TOKEN_CONST::MUTEX lock_;
ACE_Mutex_Token used to lock internal data structures.
typedef ACE_Token_Name TOKEN_NAME;
This may be changed to a template type.
typedef ACE_Map_Manager<TOKEN_NAME, ACE_Tokens *, ACE_Null_Mutex> COLLECTION;
COLLECTION maintains a mapping from token names to ACE_Tokens*
typedef ACE_Map_Iterator<TOKEN_NAME, ACE_Tokens *, ACE_Null_Mutex> COLLECTION_ITERATOR;
Allows iterations through collection_
typedef ACE_Map_Entry<TOKEN_NAME, ACE_Tokens *> COLLECTION_ENTRY;
Allows iterations through collection_
COLLECTION collection_;
COLLECTION maintains a mapping from token names to ACE_Tokens*.
AUTHOR
Tim Harrison (harrison@cs.wustl.edu)
EXTENDING TOKENS
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.
LIBRARY
ace