Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

ACE_Token_Manager Class Reference

Manages all tokens in a process space. More...

#include <Token_Manager.h>

Inheritance diagram for ACE_Token_Manager:

Inheritance graph
[legend]
Collaboration diagram for ACE_Token_Manager:

Collaboration graph
[legend]
List of all members.

Public Methods

 ACE_Token_Manager (void)
virtual ~ACE_Token_Manager (void)
void instance (ACE_Token_Manager *)
 Set the pointer to token manager singleton. More...

void get_token (ACE_Token_Proxy *, const ACE_TCHAR *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)
 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. More...

ACE_TOKEN_CONST::MUTEXmutex (void)
void dump (void) const
 Dump the state of the class. More...

void debug (int d)
 Turn debug mode on/off. More...


Static Public Methods

ACE_Token_Manager * instance (void)
 Get the pointer to token manager singleton. More...


Private Types

typedef ACE_Token_Name TOKEN_NAME
 This may be changed to a template type. More...

typedef ACE_Map_Manager< TOKEN_NAME,
ACE_Tokens *, ACE_Null_Mutex
COLLECTION
 COLLECTION maintains a mapping from token names to ACE_Tokens*. More...

typedef ACE_Map_Iterator<
TOKEN_NAME, ACE_Tokens *,
ACE_Null_Mutex
COLLECTION_ITERATOR
 Allows iterations through collection_. More...

typedef ACE_Map_Entry< TOKEN_NAME,
ACE_Tokens * > 
COLLECTION_ENTRY
 Allows iterations through collection_. More...


Private Methods

ACE_Tokenstoken_waiting_for (const ACE_TCHAR *client_id)
 Return the token that the given client_id is waiting for, if any. More...


Private Attributes

int debug_
 Whether to print debug messages or not. More...

ACE_TOKEN_CONST::MUTEX lock_
 ACE_Mutex_Token used to lock internal data structures. More...

COLLECTION collection_
 COLLECTION maintains a mapping from token names to ACE_Tokens*. More...


Static Private Attributes

ACE_Token_Manager * token_manager_ = 0
 pointer to singleton token manager. More...


Detailed Description

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.

Definition at line 42 of file Token_Manager.h.


Member Typedef Documentation

typedef ACE_Map_Manager<TOKEN_NAME, ACE_Tokens *, ACE_Null_Mutex> ACE_Token_Manager::COLLECTION [private]
 

COLLECTION maintains a mapping from token names to ACE_Tokens*.

Definition at line 117 of file Token_Manager.h.

typedef ACE_Map_Entry<TOKEN_NAME, ACE_Tokens *> ACE_Token_Manager::COLLECTION_ENTRY [private]
 

Allows iterations through collection_.

Definition at line 125 of file Token_Manager.h.

typedef ACE_Map_Iterator<TOKEN_NAME, ACE_Tokens *, ACE_Null_Mutex> ACE_Token_Manager::COLLECTION_ITERATOR [private]
 

Allows iterations through collection_.

Definition at line 121 of file Token_Manager.h.

typedef ACE_Token_Name ACE_Token_Manager::TOKEN_NAME [private]
 

This may be changed to a template type.

Definition at line 113 of file Token_Manager.h.


Constructor & Destructor Documentation

ACE_Token_Manager::ACE_Token_Manager void   
 

Definition at line 18 of file Token_Manager.cpp.

References ACE_TRACE.

00019 {
00020   ACE_TRACE ("ACE_Token_Manager::ACE_Token_Manager");
00021 }

ACE_Token_Manager::~ACE_Token_Manager void    [virtual]
 

Definition at line 23 of file Token_Manager.cpp.

References ACE_TRACE, ACE_Map_Iterator::advance, collection_, ACE_Map_Entry< TOKEN_NAME, ACE_Tokens * >::int_id_, and ACE_Map_Iterator_Base::next.

00024 {
00025   ACE_TRACE ("ACE_Token_Manager::~ACE_Token_Manager");
00026 
00027   COLLECTION_ITERATOR iterator (collection_);
00028 
00029   for (COLLECTION_ENTRY *temp = 0;
00030        iterator.next (temp) != 0;
00031        iterator.advance ())
00032     {
00033       // @ should I be doing an unbind here?
00034       delete temp->int_id_;
00035       // The ext_id_'s delete themselves when the array of
00036       // COLLECTION_ENTRYs goes away.
00037     }
00038 }


Member Function Documentation

int ACE_Token_Manager::check_deadlock ACE_Tokens   token,
ACE_Token_Proxy   proxy
 

Definition at line 133 of file Token_Manager.cpp.

References ACE_DEBUG, ACE_LIB_TEXT, ACE_TRACE, check_deadlock, ACE_TPQ_Entry::client_id, ACE_Token_Proxy::client_id, LM_DEBUG, ACE_Tokens::name, ACE_Tokens::OWNER_STACK, ACE_Tokens::owners, ACE_Token_Proxy::token_, token_waiting_for, ACE_Tokens::visit, and ACE_Tokens::visited.

00134 {
00135   ACE_TRACE ("ACE_Token_Manager::check_deadlock");
00136 
00137   if (token->visited ())
00138     return 0;
00139 
00140   token->visit (1);
00141 
00142   ACE_Tokens::OWNER_STACK owners;
00143 
00144   int is_owner = token->owners (owners, proxy->client_id ());
00145 
00146   switch (is_owner)
00147     {
00148     case -1:
00149       // Error.
00150       return -1;
00151     case 1:
00152       // The caller is an owner, so we have a deadlock situation.
00153       if (debug_)
00154         {
00155           ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("(%t) Deadlock detected.\n")));
00156           ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("%s owns %s and is waiting for %s.\n"),
00157                       proxy->client_id (),
00158                       token->name (),
00159                       proxy->token_->name ()));
00160         }
00161 
00162       return 1;
00163     case 0:
00164     default:
00165       // Recurse on each owner.
00166       while (!owners.is_empty ())
00167         {
00168           ACE_TPQ_Entry *e;
00169           owners.pop (e);
00170           // If the owner is waiting on another token, recurse.
00171           ACE_Tokens *twf = this->token_waiting_for (e->client_id ());
00172           if ((twf != 0) &&
00173               (this->check_deadlock (twf, proxy) == 1))
00174             {
00175               if (debug_)
00176                 {
00177                   ACE_DEBUG ((LM_DEBUG,
00178                               ACE_LIB_TEXT ("%s owns %s and is waiting for %s.\n"),
00179                               e->client_id (),
00180                               token->name (),
00181                               twf->name ()));
00182                 }
00183               return 1;
00184             }
00185           // else, check the next owner.
00186         }
00187 
00188       // We've checked all the owners and found no deadlock.
00189       return 0;
00190     }
00191 }

int ACE_Token_Manager::check_deadlock ACE_Token_Proxy   proxy
 

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.

Definition at line 114 of file Token_Manager.cpp.

References ACE_TRACE, ACE_Map_Iterator::advance, collection_, ACE_Map_Entry< TOKEN_NAME, ACE_Tokens * >::int_id_, ACE_Map_Iterator_Base::next, ACE_Token_Proxy::token_, and ACE_Tokens::visit.

Referenced by ACE_RW_Token::acquire, ACE_Mutex_Token::acquire, and check_deadlock.

00115 {
00116   ACE_TRACE ("ACE_Token_Manager::check_deadlock");
00117 
00118   // Start the recursive deadlock detection algorithm.
00119   int result = this->check_deadlock (proxy->token_, proxy);
00120 
00121   // Whether or not we detect deadlock, we have to unmark all tokens
00122   // for the next time.
00123   COLLECTION_ITERATOR iterator (collection_);
00124   for (COLLECTION_ENTRY *temp = 0;
00125        iterator.next (temp) != 0;
00126        iterator.advance ())
00127       temp->int_id_->visit (0);
00128 
00129   return result;
00130 }

void ACE_Token_Manager::debug int    d
 

Turn debug mode on/off.

void ACE_Token_Manager::dump void    const
 

Dump the state of the class.

Definition at line 255 of file Token_Manager.cpp.

References ACE_BEGIN_DUMP, ACE_DEBUG, ACE_END_DUMP, ACE_LIB_TEXT, ACE_TRACE, collection_, ACE_Map_Manager< TOKEN_NAME, ACE_Tokens *, ACE_Null_Mutex >::dump, LM_DEBUG, and lock_.

00256 {
00257   ACE_TRACE ("ACE_Token_Manager::dump");
00258   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00259   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("ACE_Token_Manager::dump:\n")));
00260   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("lock_\n")));
00261   lock_.dump ();
00262   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("collection_\n")));
00263   collection_.dump ();
00264   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00265 }

void ACE_Token_Manager::get_token ACE_Token_Proxy  ,
const ACE_TCHAR   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.

Definition at line 70 of file Token_Manager.cpp.

References ACE_GUARD, ACE_TCHAR, ACE_TRACE, ACE_Map_Manager< TOKEN_NAME, ACE_Tokens *, ACE_Null_Mutex >::bind, collection_, ACE_Token_Proxy::create_token, ACE_Map_Manager< TOKEN_NAME, ACE_Tokens *, ACE_Null_Mutex >::find, ACE_Tokens::inc_reference, ACE_Null_Mutex::lock_, ACE_TOKEN_CONST::MUTEX, and ACE_Token_Proxy::token_.

Referenced by ACE_Token_Proxy::open.

00072 {
00073   ACE_TRACE ("ACE_Token_Manager::get_token");
00074   // Hmm.  I think this makes sense.  We perform our own locking here
00075   // (see safe_acquire.)  We have to make sure that only one thread
00076   // uses the collection at a time.
00077 
00078   ACE_GUARD (ACE_TOKEN_CONST::MUTEX, ace_mon, this->lock_);
00079 
00080   TOKEN_NAME name (token_name);
00081 
00082   if (collection_.find (name, proxy->token_) == -1)
00083     // We did not find one in the collection.
00084     {
00085       // Make one.
00086       proxy->token_ = proxy->create_token (token_name);
00087 
00088       // Put it in the collection.
00089       if (collection_.bind (name, proxy->token_) == -1)
00090         {
00091           delete proxy->token_;
00092           proxy->token_ = 0;
00093         }
00094     }
00095 
00096   if (proxy->token_ != 0)
00097     proxy->token_->inc_reference ();
00098 
00099   // We may be returning proxy->token_ == 0 if new failed, caller must
00100   // check.
00101 }

void ACE_Token_Manager::instance ACE_Token_Manager *   
 

Set the pointer to token manager singleton.

ACE_Token_Manager * ACE_Token_Manager::instance void    [static]
 

Get the pointer to token manager singleton.

Definition at line 41 of file Token_Manager.cpp.

References ACE_GUARD_RETURN, ACE_NEW_RETURN, ACE_TRACE, ACE_Object_Manager::at_exit, ACE_TOKEN_CONST::MUTEX, and token_manager_.

Referenced by ACE_RW_Token::acquire, ACE_Mutex_Token::acquire, ACE_Token_Proxy::open, ACE_RW_Token::tryacquire, ACE_Mutex_Token::tryacquire, and ACE_Token_Proxy::~ACE_Token_Proxy.

00042 {
00043   ACE_TRACE ("ACE_Token_Manager::instance");
00044 
00045   // This first check is to avoid acquiring the mutex in the common
00046   // case.  Double-Check pattern rules.
00047   if (token_manager_ == 0)
00048     {
00049 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00050       ACE_TOKEN_CONST::MUTEX *lock =
00051         ACE_Managed_Object<ACE_TOKEN_CONST::MUTEX>::get_preallocated_object
00052           (ACE_Object_Manager::ACE_TOKEN_MANAGER_CREATION_LOCK);
00053       ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon, *lock, 0);
00054 #endif /* ACE_MT_SAFE */
00055 
00056       if (token_manager_ == 0)
00057         {
00058           ACE_NEW_RETURN (token_manager_,
00059                           ACE_Token_Manager,
00060                           0);
00061           // Register for destruction with ACE_Object_Manager.
00062           ACE_Object_Manager::at_exit (token_manager_);
00063         }
00064     }
00065 
00066   return token_manager_;
00067 }

ACE_TOKEN_CONST::MUTEX& ACE_Token_Manager::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 ACE_Token_Manager::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.

Definition at line 214 of file Token_Manager.cpp.

References ACE_ASSERT, ACE_ERROR, ACE_GUARD, ACE_LIB_TEXT, ACE_TRACE, collection_, ACE_Tokens::dec_reference, LM_ERROR, ACE_Null_Mutex::lock_, ACE_TOKEN_CONST::MUTEX, ACE_Tokens::name, ACE_Tokens::type, and ACE_Map_Manager< TOKEN_NAME, ACE_Tokens *, ACE_Null_Mutex >::unbind.

Referenced by ACE_Token_Proxy::~ACE_Token_Proxy.

00215 {
00216   ACE_TRACE ("ACE_Token_Manager::release_token");
00217   // again, let's perform our own locking here.
00218 
00219   ACE_GUARD (ACE_TOKEN_CONST::MUTEX, ace_mon, this->lock_);
00220 
00221   if (token->dec_reference () == 0)
00222     {
00223       // No one has the token, so we can delete it and remove it from
00224       // our collection.  First, let's get it from the collection.
00225       TOKEN_NAME token_name (token->name ());
00226 
00227       ACE_Tokens *temp;
00228 
00229       if (collection_.unbind (token_name, temp) == -1)
00230         // we did not find one in the collection
00231         {
00232           errno = ENOENT;
00233           ACE_ERROR ((LM_ERROR, ACE_LIB_TEXT ("Token Manager could not release %s:%d\n"),
00234                       token->name (), token->type ()));
00235           // @@ bad
00236         }
00237       else
00238         // we found it
00239         {
00240           // sanity pointer comparison.  The token referenced by the
00241           // proxy better be the one we found in the list.
00242           ACE_ASSERT (token == temp);
00243           delete token;  // or delete temp
00244           // we set their token to zero.  if the calling proxy is
00245           // still going to be used, it had better check it's token
00246           // value before calling a method on it!
00247           token = 0;
00248         }
00249     }
00250   // else
00251   // someone is still interested in the token, so keep it around.
00252 }

ACE_Tokens * ACE_Token_Manager::token_waiting_for const ACE_TCHAR   client_id [private]
 

Return the token that the given client_id is waiting for, if any.

Definition at line 195 of file Token_Manager.cpp.

References ACE_TCHAR, ACE_Map_Iterator::advance, collection_, ACE_Map_Entry< TOKEN_NAME, ACE_Tokens * >::int_id_, ACE_Tokens::is_waiting_for, and ACE_Map_Iterator_Base::next.

Referenced by check_deadlock.

00196 {
00197   COLLECTION_ITERATOR iterator (collection_);
00198   for (COLLECTION_ENTRY *temp = 0;
00199        iterator.next (temp) != 0;
00200        iterator.advance ())
00201     {
00202       if (temp->int_id_->is_waiting_for (client_id))
00203         return temp->int_id_;
00204     }
00205 
00206   // nothing was found, return NULL.
00207   return 0;
00208 }


Member Data Documentation

COLLECTION ACE_Token_Manager::collection_ [private]
 

COLLECTION maintains a mapping from token names to ACE_Tokens*.

Definition at line 128 of file Token_Manager.h.

Referenced by check_deadlock, dump, get_token, release_token, token_waiting_for, and ~ACE_Token_Manager.

int ACE_Token_Manager::debug_ [private]
 

Whether to print debug messages or not.

Definition at line 101 of file Token_Manager.h.

ACE_TOKEN_CONST::MUTEX ACE_Token_Manager::lock_ [private]
 

ACE_Mutex_Token used to lock internal data structures.

Definition at line 110 of file Token_Manager.h.

Referenced by dump.

ACE_Token_Manager * ACE_Token_Manager::token_manager_ = 0 [static, private]
 

pointer to singleton token manager.

Definition at line 16 of file Token_Manager.cpp.

Referenced by instance.


The documentation for this class was generated from the following files:
Generated on Mon Jun 16 12:58:28 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002