#include "ace/Token_Invariants.h" #if defined (ACE_HAS_TOKENS_LIBRARY) #include "ace/Object_Manager.h" #include "ace/os_include/os_typeinfo.h" ACE_BEGIN_VERSIONED_NAMESPACE_DECL ACE_Token_Invariant_Manager *ACE_Token_Invariant_Manager::instance_ = 0; ACE_Token_Invariant_Manager * ACE_Token_Invariant_Manager::instance () { ACE_TRACE ("ACE_Token_Invariant_Manager::instance"); // Perform the Double-Check pattern... if (instance_ == 0) { ACE_MT (ACE_TOKEN_CONST::MUTEX *lock = ACE_Managed_Object::get_preallocated_object (ACE_Object_Manager::ACE_TOKEN_INVARIANTS_CREATION_LOCK); ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon, *lock, 0)); if (instance_ == 0) { ACE_NEW_RETURN (instance_, ACE_Token_Invariant_Manager, 0); // Register for destruction with ACE_Object_Manager. ACE_Object_Manager::at_exit (instance_, 0, typeid (instance_).name ()); } } return instance_; } ACE_Token_Invariant_Manager::ACE_Token_Invariant_Manager () { ACE_TRACE ("ACE_Token_Invariant_Manager::ACE_Token_Invariant_Manager"); } int ACE_Token_Invariant_Manager::mutex_acquired (const ACE_TCHAR *token_name) { ACE_TRACE ("ACE_Token_Invariant_Manager::mutex_acquired"); ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon, this->lock_, -1); ACE_Mutex_Invariants *inv = 0; if (this->get_mutex (token_name, inv) == -1) return -1; return inv->acquired (); } int ACE_Token_Invariant_Manager::acquired (const ACE_Token_Proxy *proxy) { ACE_TRACE ("ACE_Token_Invariant_Manager::acquired"); // Reach into the proxy to find the token type. if (proxy->token_->type () == ACE_Tokens::MUTEX) return this->mutex_acquired (proxy->name ()); else // ACE_Tokens::RWLOCK. { if (proxy->type () == ACE_RW_Token::READER) return this->reader_acquired (proxy->name ()); else // ACE_RW_Token::WRITER. return this->writer_acquired (proxy->name ()); } } void ACE_Token_Invariant_Manager::releasing (const ACE_Token_Proxy *proxy) { ACE_TRACE ("ACE_Token_Invariant_Manager::releasing"); // Reach into the proxy to find the token type. if (proxy->token_->type () == ACE_Tokens::MUTEX) this->mutex_releasing (proxy->name ()); else // ACE_Tokens::RWLOCK. this->rwlock_releasing (proxy->name ()); } void ACE_Token_Invariant_Manager::mutex_releasing (const ACE_TCHAR *token_name) { ACE_TRACE ("ACE_Token_Invariant_Manager::mutex_releasing"); ACE_GUARD (ACE_TOKEN_CONST::MUTEX, ace_mon, this->lock_); ACE_Mutex_Invariants *inv = 0; if (this->get_mutex (token_name, inv) == 0) inv->releasing (); } int ACE_Token_Invariant_Manager::reader_acquired (const ACE_TCHAR *token_name) { ACE_TRACE ("ACE_Token_Invariant_Manager::reader_acquired"); ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon, this->lock_, -1); ACE_RWLock_Invariants *inv = 0; if (this->get_rwlock (token_name, inv) == -1) return -1; return inv->reader_acquired (); } int ACE_Token_Invariant_Manager::writer_acquired (const ACE_TCHAR *token_name) { ACE_TRACE ("ACE_Token_Invariant_Manager::writer_acquired"); ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon, this->lock_, -1); ACE_RWLock_Invariants *inv = 0; if (this->get_rwlock (token_name, inv) == -1) return -1; return inv->writer_acquired (); } void ACE_Token_Invariant_Manager::rwlock_releasing (const ACE_TCHAR *token_name) { ACE_TRACE ("ACE_Token_Invariant_Manager::rwlock_releasing"); ACE_GUARD (ACE_TOKEN_CONST::MUTEX, ace_mon, this->lock_); ACE_RWLock_Invariants *inv = 0; if (this->get_rwlock (token_name, inv) == 0) inv->releasing (); } void ACE_Token_Invariant_Manager::dump () const { #if defined (ACE_HAS_DUMP) ACE_TRACE ("ACE_Token_Invariant_Manager::dump"); ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("mutex_collection_:\n"))); mutex_collection_.dump (); ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("rwlock_collection_:\n"))); rwlock_collection_.dump (); ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP)); #endif /* ACE_HAS_DUMP */ } int ACE_Token_Invariant_Manager::get_mutex (const ACE_TCHAR *token_name, ACE_Mutex_Invariants *&inv) { ACE_TRACE ("ACE_Token_Invariant_Manager::get_mutex"); TOKEN_NAME name (token_name); if (mutex_collection_.find (name, inv) == -1) // We did not find one in the collection. { ACE_Mutex_Invariants *new_invariant; ACE_NEW_RETURN (new_invariant, ACE_Mutex_Invariants, -1); if (mutex_collection_.bind (name, new_invariant) == -1) { delete new_invariant; return -1; } if (mutex_collection_.find (name, inv) == -1) // We did not find one in the collection. return -1; } return 0; } int ACE_Token_Invariant_Manager::get_rwlock (const ACE_TCHAR *token_name, ACE_RWLock_Invariants *&inv) { ACE_TRACE ("ACE_Token_Invariant_Manager::get_rwlock"); TOKEN_NAME name (token_name); if (rwlock_collection_.find (name, inv) == -1) // We did not find one in the collection. { ACE_RWLock_Invariants *new_invariant; ACE_NEW_RETURN (new_invariant, ACE_RWLock_Invariants, -1); if (rwlock_collection_.bind (name, new_invariant) == -1) return -1; if (rwlock_collection_.find (name, inv) == -1) // We did not find one in the collection. return -1; } return 0; } ACE_Token_Invariant_Manager::~ACE_Token_Invariant_Manager () { ACE_TRACE ("ACE_Token_Invariant_Manager::~ACE_Token_Invariant_Manager"); MUTEX_COLLECTION::ITERATOR iterator (mutex_collection_); for (MUTEX_COLLECTION::ENTRY *temp = 0; iterator.next (temp) != 0; iterator.advance ()) delete temp->int_id_; RWLOCK_COLLECTION::ITERATOR iterator2 (rwlock_collection_); for (RWLOCK_COLLECTION::ENTRY *temp2 = 0; iterator2.next (temp2) != 0; iterator2.advance ()) delete temp2->int_id_; } // ************************************************** // ************************************************** // ************************************************** int ACE_Mutex_Invariants::acquired () { if (++owners_ > 1) { owners_ = 42; return 0; } else return 1; } void ACE_Mutex_Invariants::releasing () { if (owners_ == 1) --owners_; } void ACE_Mutex_Invariants::dump () const { #if defined (ACE_HAS_DUMP) ACE_TRACE ("ACE_Mutex_Invariants::dump"); ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("owners_ = %d\n"), owners_)); ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP)); #endif /* ACE_HAS_DUMP */ } // ************************************************** int ACE_RWLock_Invariants::writer_acquired () { if (readers_ > 0) { writers_ = readers_ = 42; return 0; } else if (++writers_ > 1) { writers_ = readers_ = 42; return 0; } else return 1; } int ACE_RWLock_Invariants::reader_acquired () { if (writers_ > 0) { writers_ = readers_ = 42; return 0; } else { ++readers_; return 1; } } void ACE_RWLock_Invariants::releasing () { if (writers_ == 1) writers_ = 0; else if (readers_ > 0) --readers_; } void ACE_RWLock_Invariants::dump () const { #if defined (ACE_HAS_DUMP) ACE_TRACE ("ACE_RWLock_Invariants::dump"); ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("writers_ = %d readers_ = %d\n"), writers_, readers_)); ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP)); #endif /* ACE_HAS_DUMP */ } ACE_END_VERSIONED_NAMESPACE_DECL #endif /* ACE_HAS_TOKENS_LIBRARY */