diff options
Diffstat (limited to 'TAO/orbsvcs/orbsvcs/Concurrency/CC_LockSet.h')
-rw-r--r-- | TAO/orbsvcs/orbsvcs/Concurrency/CC_LockSet.h | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/TAO/orbsvcs/orbsvcs/Concurrency/CC_LockSet.h b/TAO/orbsvcs/orbsvcs/Concurrency/CC_LockSet.h new file mode 100644 index 00000000000..1d01ebeef27 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Concurrency/CC_LockSet.h @@ -0,0 +1,199 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file CC_LockSet.h + * + * $Id$ + * + * This class implements the lock set interface from the + * concurrency service. + * + * In the present implementation the multiple possesion semantics + * is implemented for non-transactional clients. In future + * versions this should be changed because the multiple possesion + * semantics does not apply to non-transactional clients. This + * can be accomplished in the following manner: + * - Make a class with the same functiallity as the CC_LockSet + * class as a base class for both implementations. + * - The functionallity that should be separated out in the + * subclasses is the compatible function which should always + * return false because no locks can be held simultanously with + * non-transactional clients. + * - Use these classes from the classes that inherits the + * servant properties, i.e. the way CC_LockSet does now. + * + * + * @author Torben Worm <tworm@cs.wustl.edu> + */ +//============================================================================= + + +#ifndef _CC_LOCKSET_H +#define _CC_LOCKSET_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/Thread_Mutex.h" +#include "ace/Token.h" +#include "ace/Unbounded_Queue.h" + +#include "orbsvcs/CosConcurrencyControlS.h" +#include "orbsvcs/Concurrency/concurrency_serv_export.h" + +#if defined (lock_held) +#undef lock_held +#endif /* lock_held */ + +/// This constant defines the number of lock modes. There is really no +/// way to set this constant dynamically because the nuber of lock +/// modes are not stated as part of the IDL. +#define NUMBER_OF_LOCK_MODES 5 + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +/// Enummeration representing the lock modes. The incoming request is +/// always converted to this representation. There are two reasons for +/// this: Firstly the lock modes are ordered from weakest to strongest +/// in the internal representation, and secondly it is possible to +/// indicate a 'non-mode' (CC_EM) +typedef enum {CC_EM=-1, CC_IR=0, CC_R, CC_U, CC_IW, CC_W} CC_LockModeEnum; + +/** + * @class CC_LockSet + * + * @brief CC_LockSet + * + * This class implements the LockSet interface that is part of + * the CosConcurrency service. Please consult the idl file for + * detailed descriptions apart from the comments in this file At + * present the lock set is not really a set, but only one lock. + */ +class TAO_Concurrency_Serv_Export CC_LockSet : public POA_CosConcurrencyControl::LockSet +{ +public: + + // = Initialization and termination methods. + /// Default constructor + CC_LockSet (void); + + /// Constructor used if create_related is used to create the lock + /// set. + CC_LockSet (CosConcurrencyControl::LockSet_ptr related); + + /// Destructor. + ~CC_LockSet (void); + + // = CosConcurrencyControl methods + /// Acquires this lock. Blocks until lock is obtained + virtual void lock (CosConcurrencyControl::lock_mode mode + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + + /// Tries to acquire this lock. If it is not possible to acquire the + /// lock, false is returned + virtual CORBA::Boolean try_lock (CosConcurrencyControl::lock_mode mode + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + + /// Releases this lock. + virtual void unlock (CosConcurrencyControl::lock_mode mode + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + CosConcurrencyControl::LockNotHeld)); + + /// Changes the mode of this lock. + virtual void change_mode (CosConcurrencyControl::lock_mode held_mode, + CosConcurrencyControl::lock_mode new_mode + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + CosConcurrencyControl::LockNotHeld)); + + // = Debugging methods + /// Dump the state of the object to stdout + void dump (void); + +private: + /// Converts the CORBA specification's lock mode to the internal + /// representation + CC_LockModeEnum lmconvert (CosConcurrencyControl::lock_mode mode); + + /// Initiatlizes the lock set array and acquires the initial + /// semaphore. + void Init (ACE_ENV_SINGLE_ARG_DECL); + + /// Returns true if the held lock and the requested lock are compatible + CORBA::Boolean compatible (CC_LockModeEnum mr); + + // The _i functions below ensures atomical access the the state data + // for the lock set. The functions acquires a thread lock in order + // to insure consistency within the lock set. The return value + // typically indicates whether the current thread should be + // suspended or not (by locking the semaphore. + + /// Locks the access to the data and decides whether to lock or + /// not. Returns 1 if the semaphore should be locked. + int lock_i (CC_LockModeEnum lm); + + // int unlock_i (CosConcurrencyControl::lock_mode lm); + // This function is not necessary because we lock access to the data + // and unlocks the semaphore until an invalid lock mode is first on + // the queue. Thereafter we release the lock. + + /// Locks the access to the data and determines whether to return + /// true or false. Returns 1 if true should be returned. + int try_lock_i (CC_LockModeEnum lm); + + /// Locks access to the data and determines if the semaphore should + /// be locked. Returns 1 if the semaphore should be locked. + int change_mode_i (CC_LockModeEnum lm_held, + CC_LockModeEnum lm_new); + + /// Locks access ti the data and checks whether the lock is held. + int lock_held (CC_LockModeEnum lm); + + /// An array of lock counters that counts how many locks of that type + /// that the lock set holds. + int lock_[NUMBER_OF_LOCK_MODES]; + + // ACE_Thread_Semaphore semaphore_; + /** + * This is the semaphore for the lock set. The semaphore is used to + * queue requests for locks in modes stronger than currently + * possible to grant. Note that the <ACE_Token> provides strict + * FIFO ordering of acquisition/release of the lock. + */ + ACE_Token semaphore_; + + /** + * If this lock set is related to another lock set, this is the + * pointer to the related lock set. This is a really simple + * solution, but since transactions are not supported in the first + * version there should be no reason to drop lock sets together. The + * <LockSetCoordinator> is not implemented (it has the + * responsibilities of dropping the locks). + */ + CosConcurrencyControl::LockSet_ptr related_lockset_; + + /// Mapping between requested and held lock modes. Used by compatible + /// (...). Uses the internal enumeration as indices. + static CORBA::Boolean const compatible_[NUMBER_OF_LOCK_MODES][NUMBER_OF_LOCK_MODES]; + + /// Lock to ensure that race conditions does not occur. + TAO_SYNCH_MUTEX mlock_; + + /// Queue to hold the requested locks not yet granted. + ACE_Unbounded_Queue <CC_LockModeEnum> lock_queue_; +}; + +TAO_END_VERSIONED_NAMESPACE_DECL + +#include /**/ "ace/post.h" + +#endif /* _CC_LOCKSET_H */ |