summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Schlüns <as@openoffice.org>2001-06-11 09:25:40 +0000
committerAndreas Schlüns <as@openoffice.org>2001-06-11 09:25:40 +0000
commitd6b7d070d855c71f2aaeabba9d618e31fe04d481 (patch)
tree6f015dd4368d5c9d2b8430b06e31bed910ef3d0f
parent9f8b1d25b2cb56b24770db6a834ea1c4dfb4d2ef (diff)
#85529# make it inline
-rw-r--r--framework/inc/threadhelp/fairrwlock.hxx216
-rw-r--r--framework/inc/threadhelp/gate.hxx112
-rw-r--r--framework/inc/threadhelp/readguard.hxx117
-rw-r--r--framework/inc/threadhelp/resetableguard.hxx110
-rw-r--r--framework/inc/threadhelp/transactionguard.hxx92
-rw-r--r--framework/inc/threadhelp/transactionmanager.hxx347
-rw-r--r--framework/inc/threadhelp/writeguard.hxx179
7 files changed, 994 insertions, 179 deletions
diff --git a/framework/inc/threadhelp/fairrwlock.hxx b/framework/inc/threadhelp/fairrwlock.hxx
index 3818480276..3926e748a9 100644
--- a/framework/inc/threadhelp/fairrwlock.hxx
+++ b/framework/inc/threadhelp/fairrwlock.hxx
@@ -2,9 +2,9 @@
*
* $RCSfile: fairrwlock.hxx,v $
*
- * $Revision: 1.3 $
+ * $Revision: 1.4 $
*
- * last change: $Author: as $ $Date: 2001-05-02 13:00:41 $
+ * last change: $Author: as $ $Date: 2001-06-11 10:22:39 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -74,10 +74,22 @@
#include <threadhelp/irwlock.h>
#endif
+#ifndef __FRAMEWORK_MACROS_DEBUG_HXX_
+#include <macros/debug.hxx>
+#endif
+
//_________________________________________________________________________________________________________________
// interface includes
//_________________________________________________________________________________________________________________
+#ifndef _COM_SUN_STAR_UNO_XINTERFACE_HPP_
+#include <com/sun/star/uno/XInterface.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_
+#include <com/sun/star/lang/DisposedException.hpp>
+#endif
+
//_________________________________________________________________________________________________________________
// other includes
//_________________________________________________________________________________________________________________
@@ -115,34 +127,198 @@ namespace framework{
=> It's a multi-reader/single-writer lock, which no preferred accessor.
@implements IRWlock
- @base INonCopyAble
+ @base INonCopyable
IRWLock
-
@devstatus ready to use
*//*-*************************************************************************************************************/
-
-class FairRWLock : private INonCopyAble
- , public IRWLock
+class FairRWLock : public IRWLock
+ , private INonCopyable
{
//-------------------------------------------------------------------------------------------------------------
// public methods
//-------------------------------------------------------------------------------------------------------------
public:
- //---------------------------------------------------------------------------------------------------------
- // ctor/dtor
- //---------------------------------------------------------------------------------------------------------
- FairRWLock();
-
- //---------------------------------------------------------------------------------------------------------
- // IRWLock
- //---------------------------------------------------------------------------------------------------------
- virtual void SAL_CALL acquireReadAccess ();
- virtual void SAL_CALL releaseReadAccess ();
- virtual void SAL_CALL acquireWriteAccess ();
- virtual void SAL_CALL releaseWriteAccess ();
- virtual void SAL_CALL downgradeWriteAccess();
+ /*-****************************************************************************************************//**
+ @short standard ctor
+ @descr Initialize instance with right start values for correct working.
+ no reader could exist => m_nReadCount = 0
+ don't block first comming writer => m_aWriteCondition.set()
+
+ @seealso -
+
+ @param -
+ @return -
+
+ @onerror -
+ *//*-*****************************************************************************************************/
+ inline FairRWLock()
+ : m_nReadCount( 0 )
+ {
+ m_aWriteCondition.set();
+ }
+
+ /*-****************************************************************************************************//**
+ @interface IRWLock
+ @short set lock for reading
+ @descr A guard should call this method to acquire read access on your member.
+ Writing isn't allowed then - but nobody could check it for you!
+
+ @seealso method releaseReadAccess()
+
+ @param -
+ @return -
+
+ @onerror -
+ *//*-*****************************************************************************************************/
+ inline virtual void acquireReadAccess()
+ {
+ // Put call in "SERIALIZE"-queue!
+ // After successful acquiring this mutex we are alone ...
+ ::osl::MutexGuard aSerializeGuard( m_aSerializer );
+
+ // ... but we should synchronize us with other reader!
+ // May be - they will unregister himself by using releaseReadAccess()!
+ ::osl::MutexGuard aAccessGuard( m_aAccessLock );
+
+ // Now we must register us as reader by increasing counter.
+ // If this the first writer we must close door for possible writer.
+ // Other reader don't look for this barrier - they work parallel to us!
+ if( m_nReadCount == 0 )
+ {
+ m_aWriteCondition.reset();
+ }
+ ++m_nReadCount;
+ }
+
+ /*-****************************************************************************************************//**
+ @interface IRWLock
+ @short reset lock for reading
+ @descr A guard should call this method to release read access on your member.
+
+ @seealso method acquireReadAccess()
+
+ @param -
+ @return -
+
+ @onerror -
+ *//*-*****************************************************************************************************/
+ inline virtual void releaseReadAccess()
+ {
+ // The access lock is enough at this point
+ // because it's not allowed to wait for all reader or writer here!
+ // That will cause a deadlock!
+ ::osl::MutexGuard aAccessGuard( m_aAccessLock );
+
+ // Unregister as reader first!
+ // Open writer barrier then if it was the last reader.
+ --m_nReadCount;
+ if( m_nReadCount == 0 )
+ {
+ m_aWriteCondition.set();
+ }
+ }
+
+ /*-****************************************************************************************************//**
+ @interface IRWLock
+ @short set lock for writing
+ @descr A guard should call this method to acquire write access on your member.
+ Reading is allowed too - of course.
+ After successfully calling of this method you are the only writer.
+
+ @seealso method releaseWriteAccess()
+
+ @param -
+ @return -
+
+ @onerror -
+ *//*-*****************************************************************************************************/
+ inline virtual void acquireWriteAccess()
+ {
+ // You have to stand in our serialize-queue till all reader
+ // are registered (not for releasing them!) or writer finished their work!
+ // Don't use a guard to do so - because you must hold the mutex till
+ // you call releaseWriteAccess()!
+ // After succesfull acquire you have to wait for current working reader.
+ // Used condition will open by last gone reader object.
+ m_aSerializer.acquire();
+ m_aWriteCondition.wait();
+
+ #ifdef ENABLE_MUTEXDEBUG
+ // A writer is an exclusiv accessor!
+ LOG_ASSERT2( m_nReadCount!=0, "FairRWLock::acquireWriteAccess()", "No threadsafe code detected ... : Read count != 0!" )
+ #endif
+ }
+
+ /*-****************************************************************************************************//**
+ @interface IRWLock
+ @short reset lock for writing
+ @descr A guard should call this method to release write access on your member.
+
+ @seealso method acquireWriteAccess()
+
+ @param -
+ @return -
+
+ @onerror -
+ *//*-*****************************************************************************************************/
+ inline virtual void releaseWriteAccess()
+ {
+ // The only one you have to do here is to release
+ // hold seriliaze-mutex. All other user of these instance are blocked
+ // by these mutex!
+ // You don't need any other mutex here - you are the only one in the moment!
+
+ #ifdef ENABLE_MUTEXDEBUG
+ // A writer is an exclusiv accessor!
+ LOG_ASSERT2( m_nReadCount!=0, "FairRWLock::releaseWriteAccess()", "No threadsafe code detected ... : Read count != 0!" )
+ #endif
+
+ m_aSerializer.release();
+ }
+
+ /*-****************************************************************************************************//**
+ @interface IRWLock
+ @short downgrade a write access to a read access
+ @descr A guard should call this method to change a write to a read access.
+ New readers can work too - new writer are blocked!
+
+ @attention Don't call this method if you are not a writer!
+ Results are not defined then ...
+ An upgrade can't be implemented realy ... because acquiring new access
+ will be the same - there no differences!
+
+ @seealso -
+
+ @param -
+ @return -
+
+ @onerror -
+ *//*-*****************************************************************************************************/
+ inline virtual void downgradeWriteAccess()
+ {
+ // You must be a writer to call this method!
+ // We can't check it - but otherwise it's your problem ...
+ // Thats why you don't need any mutex here.
+
+ #ifdef ENABLE_MUTEXDEBUG
+ // A writer is an exclusiv accessor!
+ LOG_ASSERT2( m_nReadCount!=0, "FairRWLock::downgradeWriteAccess()", "No threadsafe code detected ... : Read count != 0!" )
+ #endif
+
+ // Register himself as "new" reader.
+ // This value must be 0 before - because we support single writer access only!
+ ++m_nReadCount;
+ // Close barrier for other writer!
+ // Why?
+ // You hold the serializer mutex - next one can be a reader OR a writer.
+ // They must blocked then - because you will be a reader after this call
+ // and writer use this condition to wait for current reader!
+ m_aWriteCondition.reset();
+ // Open door for next waiting thread in serialize queue!
+ m_aSerializer.release();
+ }
//-------------------------------------------------------------------------------------------------------------
// private member
diff --git a/framework/inc/threadhelp/gate.hxx b/framework/inc/threadhelp/gate.hxx
index fc43e80015..a64c112fb7 100644
--- a/framework/inc/threadhelp/gate.hxx
+++ b/framework/inc/threadhelp/gate.hxx
@@ -2,9 +2,9 @@
*
* $RCSfile: gate.hxx,v $
*
- * $Revision: 1.1 $
+ * $Revision: 1.2 $
*
- * last change: $Author: as $ $Date: 2001-03-29 13:17:11 $
+ * last change: $Author: as $ $Date: 2001-06-11 10:23:00 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -70,6 +70,10 @@
#include <threadhelp/inoncopyable.h>
#endif
+#ifndef __FRAMEWORK_THREADHELP_IGATE_H_
+#include <threadhelp/igate.h>
+#endif
+
//_________________________________________________________________________________________________________________
// interface includes
//_________________________________________________________________________________________________________________
@@ -109,13 +113,14 @@ namespace framework{
@attention To prevent us against wrong using, the default ctor, copy ctor and the =operator are maked private!
- @implements -
- @base -
+ @implements IGate
+ @base IGate
+ INonCopyable
@devstatus ready to use
*//*-*************************************************************************************************************/
-
-class Gate : private INonCopyAble
+class Gate : public IGate
+ , private INonCopyable
{
//-------------------------------------------------------------------------------------------------------------
// public methods
@@ -133,8 +138,12 @@ class Gate : private INonCopyAble
@onerror -
*//*-*****************************************************************************************************/
-
- Gate();
+ inline Gate()
+ : m_bClosed ( sal_False )
+ , m_bGapOpen ( sal_False )
+ {
+ open();
+ }
/*-****************************************************************************************************//**
@short dtor
@@ -149,10 +158,13 @@ class Gate : private INonCopyAble
@onerror -
*//*-*****************************************************************************************************/
-
- ~Gate();
+ inline ~Gate()
+ {
+ open();
+ }
/*-****************************************************************************************************//**
+ @interface IGate
@short open the gate
@descr A wait() call will not block then.
@@ -163,10 +175,19 @@ class Gate : private INonCopyAble
@onerror -
*//*-*****************************************************************************************************/
-
- void open();
+ inline virtual void open()
+ {
+ // We must safe access to our internal member!
+ ::osl::MutexGuard aLock( m_aAccessLock );
+ // Set condition -> wait don't block any longer -> gate is open
+ m_aPassage.set();
+ // Check if operation was successful!
+ // Check returns false if condition isn't set => m_bClosed will be true then => we must return false; opening failed
+ m_bClosed = ( m_aPassage.check() == sal_False );
+ }
/*-****************************************************************************************************//**
+ @interface IGate
@short close the gate
@descr A wait() call will block then.
@@ -177,10 +198,19 @@ class Gate : private INonCopyAble
@onerror -
*//*-*****************************************************************************************************/
-
- void close();
+ inline virtual void close()
+ {
+ // We must safe access to our internal member!
+ ::osl::MutexGuard aLock( m_aAccessLock );
+ // Reset condition -> wait blocks now -> gate is closed
+ m_aPassage.reset();
+ // Check if operation was successful!
+ // Check returns false if condition was reseted => m_bClosed will be true then => we can return true; closing ok
+ m_bClosed = ( m_aPassage.check() == sal_False );
+ }
/*-****************************************************************************************************//**
+ @interface IGate
@short open gate for current waiting threads
@descr All current waiting threads stand in wait() at line "m_aPassage.wait()" ...
With this call you can open the passage for these waiting ones.
@@ -194,10 +224,19 @@ class Gate : private INonCopyAble
@onerror -
*//*-*****************************************************************************************************/
-
- void openGap();
+ inline virtual void openGap()
+ {
+ // We must safe access to our internal member!
+ ::osl::MutexGuard aLock( m_aAccessLock );
+ // Open passage for current waiting threads.
+ m_aPassage.set();
+ // Check state of condition.
+ // If condition is set check() returns true => m_bGapOpen will be true too => we can use it as return value.
+ m_bGapOpen = ( m_aPassage.check() == sal_True );
+ }
/*-****************************************************************************************************//**
+ @interface IGate
@short must be called to pass the gate
@descr If gate "open" => wait() will not block.
If gate "closed" => wait() will block till somewhere open it again.
@@ -212,23 +251,30 @@ class Gate : private INonCopyAble
@onerror We return false.
*//*-*****************************************************************************************************/
-
- sal_Bool wait( const TimeValue* pTimeOut = NULL );
-
- /*-****************************************************************************************************//**
- @short get information about current opening state
- @descr Use it if you not shure what going on ... but I think this never should realy neccessary!
-
- @seealso -
-
- @param -
- @return true, if gate is open
- false, otherwise
-
- @onerror No error could occure!
- *//*-*****************************************************************************************************/
-
- sal_Bool isOpen() const;
+ inline virtual sal_Bool wait( const TimeValue* pTimeOut = NULL )
+ {
+ // We must safe access to our internal member!
+ ::osl::ClearableMutexGuard aLock( m_aAccessLock );
+ // If gate not closed - caller can pass it.
+ sal_Bool bSuccessful = sal_True;
+ if( m_bClosed == sal_True )
+ {
+ // Otherwise first new thread must close an open gap!
+ if( m_bGapOpen == sal_True )
+ {
+ m_bGapOpen = sal_False;
+ m_aPassage.reset();
+ }
+ // Then we must release used access lock -
+ // because next call will block ...
+ // and if we hold the access lock nobody else can use this object without a dadlock!
+ aLock.clear();
+ // Wait for opening gate ...
+ bSuccessful = ( m_aPassage.wait( pTimeOut ) == osl_cond_result_ok );
+ }
+
+ return bSuccessful;
+ }
//-------------------------------------------------------------------------------------------------------------
// private member
diff --git a/framework/inc/threadhelp/readguard.hxx b/framework/inc/threadhelp/readguard.hxx
index ccca45d67a..402c2424a6 100644
--- a/framework/inc/threadhelp/readguard.hxx
+++ b/framework/inc/threadhelp/readguard.hxx
@@ -2,9 +2,9 @@
*
* $RCSfile: readguard.hxx,v $
*
- * $Revision: 1.3 $
+ * $Revision: 1.4 $
*
- * last change: $Author: as $ $Date: 2001-05-02 13:00:41 $
+ * last change: $Author: as $ $Date: 2001-06-11 10:24:13 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -74,6 +74,10 @@
#include <threadhelp/irwlock.h>
#endif
+//#ifndef __FRAMEWORK_THREADHELP_THREADHELPBASE_HXX_
+//#include <threadhelp/threadhelpbase.hxx>
+//#endif
+
//_________________________________________________________________________________________________________________
// interface includes
//_________________________________________________________________________________________________________________
@@ -82,6 +86,10 @@
// other includes
//_________________________________________________________________________________________________________________
+#ifndef _SAL_TYPES_H_
+#include <sal/types.h>
+#endif
+
//_________________________________________________________________________________________________________________
// namespace
//_________________________________________________________________________________________________________________
@@ -103,33 +111,106 @@ namespace framework{
We never need a own mutex to safe our internal member access - because
a guard is used as function-local member only. There exist no multithreaded access to it realy ...
- @attention To prevent us against wrong using, the default ctor, copy ctor and the =operator are maked private!
+ @attention a) To prevent us against wrong using, the default ctor, copy ctor and the =operator are maked private!
+ b) Use interface "IRWLock" of set LockHelper only - because we must support a finer granularity of locking.
+ Interface "IMutex" should be used by easier guard implementations ... like "ResetableGuard"!
@implements -
- @base INonCopyAble
+ @base INonCopyable
@devstatus ready to use
*//*-*************************************************************************************************************/
-class ReadGuard : private INonCopyAble
+class ReadGuard : private INonCopyable
{
//-------------------------------------------------------------------------------------------------------------
// public methods
//-------------------------------------------------------------------------------------------------------------
public:
- //---------------------------------------------------------------------------------------------------------
- // ctor/dtor
- //---------------------------------------------------------------------------------------------------------
- ReadGuard ( IRWLock* pLock );
- ReadGuard ( IRWLock& rLock );
- ~ReadGuard ( );
+ /*-****************************************************************************************************//**
+ @short ctor
+ @descr These ctors initialize the guard with a reference to used lock member of object to protect.
+ Null isn't allowed as value!
- //---------------------------------------------------------------------------------------------------------
- // interface
- //---------------------------------------------------------------------------------------------------------
- void lock () ;
- void unlock () ;
- sal_Bool isLocked () const;
+ @seealso -
+
+ @param "pLock" ,reference to used lock member of object to protect
+ @param "rLock" ,reference to used lock member of object to protect
+ @return -
+
+ @onerror -
+ *//*-*****************************************************************************************************/
+ inline ReadGuard( IRWLock* pLock )
+ : m_pLock ( pLock )
+ , m_bLocked ( sal_False )
+ {
+ lock();
+ }
+
+ //*********************************************************************************************************
+ inline ReadGuard( IRWLock& rLock )
+ : m_pLock ( &rLock )
+ , m_bLocked ( sal_False )
+ {
+ lock();
+ }
+
+ /*-****************************************************************************************************//**
+ @short dtor
+ @descr We unlock the used lock member automaticly if user forget it.
+
+ @seealso -
+
+ @param -
+ @return -
+
+ @onerror -
+ *//*-*****************************************************************************************************/
+ inline ~ReadGuard()
+ {
+ unlock();
+ }
+
+ /*-****************************************************************************************************//**
+ @short set read lock
+ @descr Call this method to set the read lock. The call will block till all current threads are synchronized!
+
+ @seealso method unlock()
+
+ @param -
+ @return -
+
+ @onerror -
+ *//*-*****************************************************************************************************/
+ inline void lock()
+ {
+ if( m_bLocked == sal_False )
+ {
+ m_pLock->acquireReadAccess();
+ m_bLocked = sal_True;
+ }
+ }
+
+ /*-****************************************************************************************************//**
+ @short unset read lock
+ @descr Call this method to unlock the rw-lock temp.!
+ Normaly we do it at dtor automaticly for you ...
+
+ @seealso method lock()
+
+ @param -
+ @return -
+
+ @onerror -
+ *//*-*****************************************************************************************************/
+ inline void unlock()
+ {
+ if( m_bLocked == sal_True )
+ {
+ m_pLock->releaseReadAccess();
+ m_bLocked = sal_False;
+ }
+ }
//-------------------------------------------------------------------------------------------------------------
// private methods
@@ -155,7 +236,7 @@ class ReadGuard : private INonCopyAble
//-------------------------------------------------------------------------------------------------------------
private:
- IRWLock* m_pLock ; /// refrence to lock-member of protected object
+ IRWLock* m_pLock ; /// reference to lock-member of protected object
sal_Bool m_bLocked ; /// protection against multiple lock calls without unlock!
}; // class ReadGuard
diff --git a/framework/inc/threadhelp/resetableguard.hxx b/framework/inc/threadhelp/resetableguard.hxx
index 0f0f67276a..fcf8b6f409 100644
--- a/framework/inc/threadhelp/resetableguard.hxx
+++ b/framework/inc/threadhelp/resetableguard.hxx
@@ -2,9 +2,9 @@
*
* $RCSfile: resetableguard.hxx,v $
*
- * $Revision: 1.1 $
+ * $Revision: 1.2 $
*
- * last change: $Author: as $ $Date: 2001-03-29 13:17:11 $
+ * last change: $Author: as $ $Date: 2001-06-11 10:24:36 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -70,6 +70,14 @@
#include <threadhelp/inoncopyable.h>
#endif
+#ifndef __FRAMEWORK_THREADHELP_IMUTEX_H_
+#include <threadhelp/imutex.h>
+#endif
+
+//#ifndef __FRAMEWORK_THREADHELP_THREADHELPBASE_HXX_
+//#include <threadhelp/threadhelpbase.hxx>
+//#endif
+
//_________________________________________________________________________________________________________________
// interface includes
//_________________________________________________________________________________________________________________
@@ -78,8 +86,8 @@
// other includes
//_________________________________________________________________________________________________________________
-#ifndef _OSL_MUTEX_HXX_
-#include <osl/mutex.hxx>
+#ifndef _SAL_TYPES_H_
+#include <sal/types.h>
#endif
//_________________________________________________________________________________________________________________
@@ -103,15 +111,16 @@ namespace framework{
A set bool flag inside protect this implementation against multiple lock() calls
without any unlock()! So the increasing of guarded mutex couldn't be greater then 1 ...
- @attention To prevent us against wrong using, the default ctor, copy ctor and the =operator are maked private!
+ @attention a) To prevent us against wrong using, the default ctor, copy ctor and the =operator are maked private!
+ b) Use interface "IMutex" of set LockHelper only - because we must support an exclusiv locking.
+ Interface "IRWLock" should be used by special guard implementations ... like "ReadGuard" or "WriteGuard"!
@implements -
- @base INonCopyAble
+ @base INonCopyable
@devstatus ready to use
*//*-*************************************************************************************************************/
-
-class ResetableGuard : private INonCopyAble
+class ResetableGuard : private INonCopyable
{
//-------------------------------------------------------------------------------------------------------------
// public methods
@@ -121,19 +130,30 @@ class ResetableGuard : private INonCopyAble
/*-****************************************************************************************************//**
@short ctors
@descr Use these ctor methods to initialize the guard right.
- Given mutex reference must be valid - otherwise crashes could occure!
+ Given lock reference must be valid - otherwise crashes could occure!
@seealso -
- @param "pMutex" pointer to mutex for using as lock
- @param "rMutex" reference to mutex for using as lock
+ @param "pLock", pointer to lock helper of user
+ @param "rLock", reference to lock helper of user
@return -
@onerror -
*//*-*****************************************************************************************************/
-
- ResetableGuard( ::osl::Mutex* pMutex );
- ResetableGuard( ::osl::Mutex& rMutex );
+ inline ResetableGuard( IMutex* pLock )
+ : m_pLock ( pLock )
+ , m_bLocked ( sal_False )
+ {
+ lock();
+ }
+
+ //*********************************************************************************************************
+ inline ResetableGuard( IMutex& rLock )
+ : m_pLock ( &rLock )
+ , m_bLocked ( sal_False )
+ {
+ lock();
+ }
/*-****************************************************************************************************//**
@short dtor
@@ -146,15 +166,17 @@ class ResetableGuard : private INonCopyAble
@onerror -
*//*-*****************************************************************************************************/
-
- ~ResetableGuard();
+ inline ~ResetableGuard()
+ {
+ unlock();
+ }
/*-****************************************************************************************************//**
@short enable/disable the lock
@descr Use this methods to lock or unlock the mutex.
You can do it so often you wish to do that ...
- @attention We use another member to prevent us against multiple acquire calls of the same guard
+ @attention We use another member to prevent us against multiple acquire calls of the same guard
without suitable release calls!
You don't must protect access at these bool member by using an own mutex ....
because nobody use the same guard instance from different threads!
@@ -167,39 +189,24 @@ class ResetableGuard : private INonCopyAble
@onerror -
*//*-*****************************************************************************************************/
-
- void lock();
- void unlock();
-
- /*-****************************************************************************************************//**
- @short try to lock the mutex
- @descr Try to acquire the mutex without blocking.
-
- @seealso -
-
- @param -
- @return true, if lock already set or could new acquired
- false, otherwise
-
- @onerror No error could occure.
- *//*-*****************************************************************************************************/
-
- sal_Bool tryToLock();
-
- /*-****************************************************************************************************//**
- @short get information about current lock state
- @descr Use it if you not shure what going on ... but I think this never should realy neccessary!
-
- @seealso -
-
- @param -
- @return true, if lock is set
- false, otherwise
-
- @onerror No error could occure!
- *//*-*****************************************************************************************************/
-
- sal_Bool isLocked() const;
+ inline void lock()
+ {
+ if( m_bLocked == sal_False )
+ {
+ m_pLock->acquire();
+ m_bLocked = sal_True;
+ }
+ }
+
+ //*********************************************************************************************************
+ inline void unlock()
+ {
+ if( m_bLocked == sal_True )
+ {
+ m_pLock->release();
+ m_bLocked = sal_False;
+ }
+ }
//-------------------------------------------------------------------------------------------------------------
// private methods
@@ -218,7 +225,6 @@ class ResetableGuard : private INonCopyAble
@onerror -
*//*-*****************************************************************************************************/
-
ResetableGuard();
//-------------------------------------------------------------------------------------------------------------
@@ -226,7 +232,7 @@ class ResetableGuard : private INonCopyAble
//-------------------------------------------------------------------------------------------------------------
private:
- ::osl::Mutex* m_pMutex ; /// pointer to safed mutex
+ IMutex* m_pLock ; /// pointer to safed lock member of user
sal_Bool m_bLocked ; /// protection against multiple lock() calls without unlock()
}; // class ResetableGuard
diff --git a/framework/inc/threadhelp/transactionguard.hxx b/framework/inc/threadhelp/transactionguard.hxx
index c9409578a8..6d00f3cbd5 100644
--- a/framework/inc/threadhelp/transactionguard.hxx
+++ b/framework/inc/threadhelp/transactionguard.hxx
@@ -2,9 +2,9 @@
*
* $RCSfile: transactionguard.hxx,v $
*
- * $Revision: 1.1 $
+ * $Revision: 1.2 $
*
- * last change: $Author: as $ $Date: 2001-05-02 13:00:41 $
+ * last change: $Author: as $ $Date: 2001-06-11 10:24:51 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -109,28 +109,90 @@ namespace framework{
@attention To prevent us against wrong using, the default ctor, copy ctor and the =operator are maked private!
@implements -
- @base INonCopyAble
+ @base INonCopyable
@devstatus draft
*//*-*************************************************************************************************************/
-class TransactionGuard : private INonCopyAble
+class TransactionGuard : private INonCopyable
{
//-------------------------------------------------------------------------------------------------------------
// public methods
//-------------------------------------------------------------------------------------------------------------
public:
- //-------------------------------------------------------------------------------------------------------------
- // ctor/dtor
- //-------------------------------------------------------------------------------------------------------------
- TransactionGuard( ITransactionManager* pManager, EExceptionMode eMode, ERejectReason* eReason = NULL );
- TransactionGuard( ITransactionManager& rManager, EExceptionMode eMode, ERejectReason* eReason = NULL );
- ~TransactionGuard( );
-
- //-------------------------------------------------------------------------------------------------------------
- // interface
- //-------------------------------------------------------------------------------------------------------------
- void stop();
+ /*-****************************************************************************************************//**
+ @short ctors
+ @descr Use these ctor methods to initialize the guard right.
+ Given reference must be valid - otherwise crashes could occure!
+
+ @attention It's not neccessary to lock any mutex here! Because a ctor should not be called
+ from different threads at the same time ... this class use no refcount mechanism!
+
+ @seealso -
+
+ @param "rManager" reference to transaction manager for using to register a request
+ @param "eMode" enable/disable throwing of exceptions for rejected calls
+ @param "eReason" returns reason for rejected calls if "eMode=E_NOEXCEPTIONS"!
+ @return -
+
+ @onerror -
+ *//*-*****************************************************************************************************/
+ inline TransactionGuard( ITransactionManager& rManager, EExceptionMode eMode, ERejectReason* eReason = NULL )
+ : m_pManager( &rManager )
+ {
+ // If exception mode is set to E_HARDEXCETIONS we don't need a buffer to return reason!
+ // We handle it private. If a call is rejected, our manager throw some exceptions ... and the reason
+ // could be ignorable ...
+ if( eReason == NULL )
+ {
+ ERejectReason eMyReason;
+ m_pManager->registerTransaction( eMode, eMyReason );
+ }
+ else
+ {
+ m_pManager->registerTransaction( eMode, *eReason );
+ }
+ }
+
+ /*-************************************************************************************************************//**
+ @short dtor
+ @descr We must release the transaction manager and can forget his pointer.
+
+ @seealso -
+
+ @param -
+ @return -
+
+ @onerror -
+ *//*-*************************************************************************************************************/
+ inline ~TransactionGuard()
+ {
+ stop();
+ }
+
+ /*-************************************************************************************************************//**
+ @short stop current transaction
+ @descr We must release the transaction manager and can forget his pointer.
+
+ @attention We don't support any start() method here - because it is not easy to
+ detect if a transaction already started or not!
+ (combination of EExceptionMode and ERejectReason)
+
+ @seealso -
+
+ @param -
+ @return -
+
+ @onerror -
+ *//*-*************************************************************************************************************/
+ inline void stop()
+ {
+ if( m_pManager != NULL )
+ {
+ m_pManager->unregisterTransaction();
+ m_pManager = NULL;
+ }
+ }
//-------------------------------------------------------------------------------------------------------------
// private methods
diff --git a/framework/inc/threadhelp/transactionmanager.hxx b/framework/inc/threadhelp/transactionmanager.hxx
index fc9143cde3..5f8a2d5e0f 100644
--- a/framework/inc/threadhelp/transactionmanager.hxx
+++ b/framework/inc/threadhelp/transactionmanager.hxx
@@ -2,9 +2,9 @@
*
* $RCSfile: transactionmanager.hxx,v $
*
- * $Revision: 1.2 $
+ * $Revision: 1.3 $
*
- * last change: $Author: as $ $Date: 2001-05-03 11:48:30 $
+ * last change: $Author: as $ $Date: 2001-06-11 10:25:06 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -78,6 +78,10 @@
#include <threadhelp/gate.hxx>
#endif
+#ifndef __FRAMEWORK_MACROS_DEBUG_HXX_
+#include <macros/debug.hxx>
+#endif
+
//_________________________________________________________________________________________________________________
// interface includes
//_________________________________________________________________________________________________________________
@@ -113,37 +117,342 @@ namespace framework{
and react for it. You can enable automaticly throwing of exceptions too.
@implements ITransactionManager
- @base INonCopyAble
+ @base INonCopyable
ITransactionManager
@devstatus draft
*//*-*************************************************************************************************************/
-class TransactionManager : private INonCopyAble
- , public ITransactionManager
+class TransactionManager : public ITransactionManager
+ , private INonCopyable
{
//-------------------------------------------------------------------------------------------------------------
// public methods
//-------------------------------------------------------------------------------------------------------------
public:
- //---------------------------------------------------------------------------------------------------------
- // ctor/dtor
- //---------------------------------------------------------------------------------------------------------
- TransactionManager();
-
- //---------------------------------------------------------------------------------------------------------
- // IRWLock
- //---------------------------------------------------------------------------------------------------------
- virtual EWorkingMode SAL_CALL getWorkingMode ( ) const;
- virtual void SAL_CALL setWorkingMode ( EWorkingMode eMode ) ;
- virtual sal_Bool SAL_CALL isCallRejected ( ERejectReason& eReason ) const;
- virtual void SAL_CALL acquire ( EExceptionMode eMode , ERejectReason& eReason ) throw( css::uno::RuntimeException, css::lang::DisposedException );
- virtual void SAL_CALL release ( );
+
+ /*-************************************************************************************************************//**
+ @short standard ctor
+ @descr Initialize instance with right start values for correct working.
+
+ @seealso -
+
+ @param -
+ @return -
+
+ @onerror -
+ *//*-*************************************************************************************************************/
+ inline TransactionManager()
+ : m_eWorkingMode ( E_INIT )
+ , m_nTransactionCount ( 0 )
+ {
+ m_aBarrier.open();
+ }
+
+ /*-****************************************************************************************************//**
+ @interface ITransactionManager
+ @short set new working mode
+ @descr These implementation knows for states of working: E_INIT, E_WORK, E_CLOSING, E_CLOSE
+ You can step during this ones only from the left to the right side and start at left side again!
+ (This is neccessary e.g. for refcounted objects!)
+ This call will block till all current existing transactions was finished.
+ Follow results occure:
+ E_INIT : All requests on this implementation are refused.
+ It's your decision to react in a right way.
+
+ E_WORK : The object can work now. The full functionality is available.
+
+ E_BEFORECLOSE : The object start the closing mechanism ... but sometimes
+ e.g. the dispose() method need to call some private methods.
+ These some special methods should use E_SOFTEXCEPTIONS or ignore
+ E_INCLOSE as returned reason for E_NOEXCEPTIONS to detect this special case!
+
+ E_CLOSE : Object is already dead! All further requests will be refused.
+ It's your decision to react in a right way.
+
+ @seealso -
+
+ @param "eMode", is the new mode - but we don't accept setting mode in wrong order!
+ @return -
+
+ @onerror We do nothing.
+ *//*-*****************************************************************************************************/
+ inline virtual void setWorkingMode( EWorkingMode eMode )
+ {
+ // Safe member access.
+ ::osl::ClearableMutexGuard aAccessGuard( m_aAccessLock );
+ sal_Bool bWaitFor = sal_False ;
+ // Change working mode first!
+ if (
+ ( m_eWorkingMode == E_INIT && eMode == E_WORK ) ||
+ ( m_eWorkingMode == E_WORK && eMode == E_BEFORECLOSE ) ||
+ ( m_eWorkingMode == E_BEFORECLOSE && eMode == E_CLOSE ) ||
+ ( m_eWorkingMode == E_CLOSE && eMode == E_INIT )
+ )
+ {
+ m_eWorkingMode = eMode;
+ if( m_eWorkingMode == E_BEFORECLOSE || m_eWorkingMode == E_CLOSE )
+ {
+ bWaitFor = sal_True;
+ }
+ }
+
+ // Wait for current existing transactions then!
+ // (Only neccessary for changing to E_BEFORECLOSE or E_CLOSE! ...
+ // otherwise; if you wait at setting E_WORK another thrad could finish a acquire-call during our unlock() and wait() call
+ // ... and we will wait forever here!!!)
+ // Don't forget to release access mutex before.
+ aAccessGuard.clear();
+ if( bWaitFor == sal_True )
+ {
+ m_aBarrier.wait();
+ }
+ }
+
+ /*-****************************************************************************************************//**
+ @interface ITransactionManager
+ @short get current working mode
+ @descr If you stand in your close() or init() method ... but don't know
+ if you called more then ones(!) ... you can use this function to get
+ right information.
+ e.g: You have a method init() which is used to change working mode from
+ E_INIT to E_WORK and should be used to initialize some member too ...
+ What should you do:
+
+ void init( sal_Int32 nValue )
+ {
+ // Reject this call if our transaction manager say: "Object already initialized!"
+ // Otherwise initialize your member.
+ if( m_aTransactionManager.getWorkingMode() == E_INIT )
+ {
+ // Object is uninitialized ...
+ // Make member access threadsafe!
+ ResetableGuard aGuard( m_aMutex );
+
+ // Check working mode again .. because anoz´ther instance could be faster.
+ // (It's possible to set this guard at first of this method too!)
+ if( m_aTransactionManager.getWorkingMode() == E_INIT )
+ {
+ m_aMember = nValue;
+
+ // Object is initialized now ... set working mode to E_WORK!
+ m_aTransactionManager.setWorkingMode( E_WORK );
+ }
+ }
+ }
+
+ @seealso method setWorkingMode()
+
+ @param -
+ @return Current set mode.
+
+ @onerror No error should occure.
+ *//*-*****************************************************************************************************/
+ inline virtual EWorkingMode getWorkingMode() const
+ {
+ // Synchronize access to internal member!
+ ::osl::MutexGuard aAccessLock( m_aAccessLock );
+ return m_eWorkingMode;
+ }
+
+ /*-****************************************************************************************************//**
+ @interface ITransactionManager
+ @short look for rejected calls
+ @descr Sometimes user need a possibility to get information about rejected calls
+ without starting a transaction!
+
+ @seealso -
+
+ @param "eReason" returns reason of a rejected call
+ @return true if call was rejected, false otherwise
+
+ @onerror We return false.
+ *//*-*****************************************************************************************************/
+ inline virtual sal_Bool isCallRejected( ERejectReason& eReason ) const
+ {
+ // This call must safe access to internal member only.
+ // Set "possible reason" for return and check reject-state then!
+ // User should look for return value first - reason then ...
+ ::osl::MutexGuard aAccessGuard( m_aAccessLock );
+ switch( m_eWorkingMode )
+ {
+ case E_INIT : eReason = E_UNINITIALIZED ;
+ break;
+ case E_WORK : eReason = E_NOREASON ;
+ break;
+ case E_BEFORECLOSE : eReason = E_INCLOSE ;
+ break;
+ case E_CLOSE : eReason = E_CLOSED ;
+ break;
+ }
+ return( eReason!=E_NOREASON );
+ }
+
+ /*-****************************************************************************************************//**
+ @interface ITransactionManager
+ @short start new transaction
+ @descr A guard should use this method to start a new transaction. He should looks for rejected
+ calls to by using parameter eMode and eReason.
+ If call was not rejected your transaction will be non breakable during releasing your transaction
+ guard! BUT ... your code isn't threadsafe then! It's a transaction manager only ....
+
+ @seealso method unregisterTransaction()
+
+ @param "eMode" ,used to enable/disable throwing exceptions automaticly for rejected calls
+ @param "eReason" ,reason for rejected calls if eMode=E_NOEXCEPTIONS
+ @return -
+
+ @onerror -
+ *//*-*****************************************************************************************************/
+ inline virtual void registerTransaction( EExceptionMode eMode, ERejectReason& eReason ) throw( css::uno::RuntimeException, css::lang::DisposedException )
+ {
+ // Look for rejected calls first.
+ // If call was refused we throw some exceptions or do nothing!
+ // It depends from given parameter eMode.
+ if( isCallRejected( eReason ) == sal_True )
+ {
+ impl_throwExceptions( eMode, eReason );
+ }
+
+ // BUT if no exception was thrown ... (may be eMode = E_SOFTEXCEPTIONS!)
+ // we must register this transaction too!
+ // Don't use "else" or a new scope here!!!
+
+ // Safe access to internal member.
+ ::osl::MutexGuard aAccessGuard( m_aAccessLock );
+
+ #ifdef ENABLE_MUTEXDEBUG
+ LOG_ASSERT2( m_nTransactionCount<0, "TransactionManager::acquire()", "Wrong ref count detected!" )
+ #endif
+
+ // Register this new transaction.
+ // If it is the first one .. close gate to disable changing of working mode.
+ ++m_nTransactionCount;
+ if( m_nTransactionCount == 1 )
+ {
+ m_aBarrier.close();
+ }
+ }
+
+ /*-****************************************************************************************************//**
+ @interface ITransactionManager
+ @short finish transaction
+ @descr A guard should call this method to release current transaction.
+
+ @seealso method registerTransaction()
+
+ @param -
+ @return -
+
+ @onerror -
+ *//*-*****************************************************************************************************/
+ inline virtual void unregisterTransaction()
+ {
+ // This call could not rejected!
+ // Safe access to internal member.
+ ::osl::MutexGuard aAccessGuard( m_aAccessLock );
+
+ #ifdef ENABLE_MUTEXDEBUG
+ LOG_ASSERT2( m_nTransactionCount<=0, "TransactionManager::release()", "Wrong ref count detected!" )
+ #endif
+
+ // Deregister this transaction.
+ // If it was the last one ... open gate to enable changing of working mode!
+ // (see setWorkingMode())
+
+ --m_nTransactionCount;
+ if( m_nTransactionCount == 0 )
+ {
+ m_aBarrier.open();
+ }
+ }
+
+ /*-****************************************************************************************************//**
+ @short return a reference to a static manager
+ @descr Sometimes we need the global member! (e.g. in our own static methods)
+ We create our own "class global static" member threadsafe.
+ It will be created at first call only!
+ All other requests use these created one then directly.
+
+ @seealso -
+
+ @param -
+ @return A reference to a static member.
+
+ @onerror No error should occure.
+ *//*-*****************************************************************************************************/
+ inline static TransactionManager& getGlobalTransactionManager()
+ {
+ // Initialize static member only for one time!
+ static TransactionManager* pManager = NULL;
+ // If these method first called (member not already exist!) ...
+ if( pManager == NULL )
+ {
+ // ... we must create a new one. Protect follow code with the global mutex -
+ // It must be - we create a static variable!
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ // We must check our pointer again - because ... another instance of ouer class could be faster then these one!
+ if( pManager == NULL )
+ {
+ // Create the new manager and set it for return on static variable.
+ static TransactionManager aManager;
+ pManager = &aManager;
+ }
+ }
+ // Return new created or already existing object.
+ return *pManager;
+ }
//-------------------------------------------------------------------------------------------------------------
// private methods
//-------------------------------------------------------------------------------------------------------------
private:
- void impl_throwExceptions( EExceptionMode eMode, ERejectReason eReason ) const throw( css::uno::RuntimeException, css::lang::DisposedException );
+
+ /*-****************************************************************************************************//**
+ @short throw any exceptions for rejected calls
+ @descr If user whish to use our automaticly exception mode we use this impl-method.
+ We check all combinations of eReason and eExceptionMode and throw right exception with some
+ descriptions for recipient of it.
+
+ @seealso method registerTransaction()
+ @seealso enum ERejectReason
+ @seealso enum EExceptionMode
+
+ @param "eReason" , reason for rejected call
+ @param "eMode" , exception mode - set by user
+ @return -
+
+ @onerror -
+ *//*-*****************************************************************************************************/
+ inline void impl_throwExceptions( EExceptionMode eMode, ERejectReason eReason ) const throw( css::uno::RuntimeException, css::lang::DisposedException )
+ {
+ if( eMode != E_NOEXCEPTIONS )
+ {
+ switch( eReason )
+ {
+ case E_UNINITIALIZED : if( eMode == E_HARDEXCEPTIONS )
+ {
+ // Help programmer to find out, why this exception is thrown!
+ LOG_ERROR( "TransactionManager...", "Owner instance not right initialized yet. Call was rejected! Normaly it's an algorithm error ... wrong usin of class!" )
+ /*ATTENTION: temp. disabled - till all bad code positions are detected and changed! */
+ // throw css::uno::RuntimeException( DECLARE_ASCII("TransactionManager...\nOwner instance not right initialized yet. Call was rejected! Normaly it's an algorithm error ... wrong usin of class!\n" ), css::uno::Reference< css::uno::XInterface >() );
+ }
+ break;
+ case E_INCLOSE : if( eMode == E_HARDEXCEPTIONS )
+ {
+ // Help programmer to find out, why this exception is thrown!
+ LOG_ERROR( "TransactionManager...", "Owner instance stand in close method. Call was rejected!" )
+ throw css::lang::DisposedException( DECLARE_ASCII("TransactionManager...\nOwner instance stand in close method. Call was rejected!\n" ), css::uno::Reference< css::uno::XInterface >() );
+ }
+ break;
+ case E_CLOSED : {
+ // Help programmer to find out, why this exception is thrown!
+ LOG_ERROR( "TransactionManager...", "Owner instance already closed. Call was rejected!" )
+ throw css::lang::DisposedException( DECLARE_ASCII("TransactionManager...\nOwner instance already closed. Call was rejected!\n" ), css::uno::Reference< css::uno::XInterface >() );
+ }
+ break;
+ }
+ }
+ }
//-------------------------------------------------------------------------------------------------------------
// private member
diff --git a/framework/inc/threadhelp/writeguard.hxx b/framework/inc/threadhelp/writeguard.hxx
index ee2a77b8c0..a0810bee16 100644
--- a/framework/inc/threadhelp/writeguard.hxx
+++ b/framework/inc/threadhelp/writeguard.hxx
@@ -2,9 +2,9 @@
*
* $RCSfile: writeguard.hxx,v $
*
- * $Revision: 1.3 $
+ * $Revision: 1.4 $
*
- * last change: $Author: as $ $Date: 2001-05-02 13:00:41 $
+ * last change: $Author: as $ $Date: 2001-06-11 10:25:40 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -74,6 +74,10 @@
#include <threadhelp/irwlock.h>
#endif
+//#ifndef __FRAMEWORK_THREADHELP_THREADHELPBASE_HXX_
+//#include <threadhelp/threadhelpbase.hxx>
+//#endif
+
//_________________________________________________________________________________________________________________
// interface includes
//_________________________________________________________________________________________________________________
@@ -102,35 +106,166 @@ namespace framework{
We never need a own mutex to safe our internal member access - because
a guard is used as function-local member only. There exist no multithreaded access to it realy ...
- @attention To prevent us against wrong using, the default ctor, copy ctor and the =operator are maked private!
+ @attention a) To prevent us against wrong using, the default ctor, copy ctor and the =operator are maked private!
+ b) Use interface "IRWLock" of set LockHelper only - because we must support a finer granularity of locking.
+ Interface "IMutex" should be used by easier guard implementations ... like "ResetableGuard"!
@implements -
- @base INonCopyAble
+ @base INonCopyable
@devstatus ready to use
*//*-*************************************************************************************************************/
-
-class WriteGuard : private INonCopyAble
+class WriteGuard : private INonCopyable
{
//-------------------------------------------------------------------------------------------------------------
// public methods
//-------------------------------------------------------------------------------------------------------------
public:
- //---------------------------------------------------------------------------------------------------------
- // ctor/dtor
- //---------------------------------------------------------------------------------------------------------
- WriteGuard ( IRWLock* pLock );
- WriteGuard ( IRWLock& rLock );
- ~WriteGuard ( );
-
- //---------------------------------------------------------------------------------------------------------
- // interface
- //---------------------------------------------------------------------------------------------------------
- void lock () ;
- void unlock () ;
- void downgrade () ;
- ELockMode getMode () const;
+ /*-****************************************************************************************************//**
+ @short ctor
+ @descr These ctors initialize the guard with a reference to used lock member of object to protect.
+ Null isn't allowed as value!
+
+ @seealso -
+
+ @param "pLock" ,reference to used lock member of object to protect
+ @param "rLock" ,reference to used lock member of object to protect
+ @return -
+
+ @onerror -
+ *//*-*****************************************************************************************************/
+ inline WriteGuard( IRWLock* pLock )
+ : m_pLock ( pLock )
+ , m_eMode ( E_NOLOCK )
+ {
+ lock();
+ }
+
+ //*********************************************************************************************************
+ inline WriteGuard( IRWLock& rLock )
+ : m_pLock ( &rLock )
+ , m_eMode ( E_NOLOCK )
+ {
+ lock();
+ }
+
+ /*-****************************************************************************************************//**
+ @short dtor
+ @descr We unlock the used lock member automaticly if user forget it.
+
+ @seealso -
+
+ @param -
+ @return -
+
+ @onerror -
+ *//*-*****************************************************************************************************/
+ inline ~WriteGuard()
+ {
+ unlock();
+ }
+
+ /*-****************************************************************************************************//**
+ @short set write lock
+ @descr Call this method to set the write lock. The call will block till all current threads are synchronized!
+
+ @seealso method unlock()
+
+ @param -
+ @return -
+
+ @onerror -
+ *//*-*****************************************************************************************************/
+ inline void lock()
+ {
+ switch( m_eMode )
+ {
+ case E_NOLOCK : {
+ // Acquire write access and set return state.
+ // Mode is set later if it was successful!
+ m_pLock->acquireWriteAccess();
+ m_eMode = E_WRITELOCK;
+ }
+ break;
+ case E_READLOCK : {
+ // User has downgrade to read access before!
+ // We must release it before we can set a new write access!
+ m_pLock->releaseReadAccess();
+ m_pLock->acquireWriteAccess();
+ m_eMode = E_WRITELOCK;
+ }
+ break;
+ }
+ }
+
+ /*-****************************************************************************************************//**
+ @short unset write lock
+ @descr Call this method to unlock the rw-lock temp.!
+ Normaly we do it at dtor automaticly for you ...
+
+ @seealso method lock()
+
+ @param -
+ @return -
+
+ @onerror -
+ *//*-*****************************************************************************************************/
+ inline void unlock()
+ {
+ switch( m_eMode )
+ {
+ case E_READLOCK : {
+ // User has downgraded to a read lock before!
+ // => There isn't realy a write lock ...
+ m_pLock->releaseReadAccess();
+ m_eMode = E_NOLOCK;
+ }
+ break;
+ case E_WRITELOCK : {
+ m_pLock->releaseWriteAccess();
+ m_eMode = E_NOLOCK;
+ }
+ break;
+ }
+ }
+
+ /*-****************************************************************************************************//**
+ @short downgrade write access to read access without new blocking!
+ @descr If this write lock is set you can change it to a "read lock".
+ An "upgrade" is the same like new calling "lock()"!
+
+ @seealso -
+
+ @param -
+ @return -
+
+ @onerror -
+ *//*-*****************************************************************************************************/
+ inline void downgrade()
+ {
+ if( m_eMode == E_WRITELOCK )
+ {
+ m_pLock->downgradeWriteAccess();
+ m_eMode = E_READLOCK;
+ }
+ }
+
+ /*-****************************************************************************************************//**
+ @short return internal states
+ @descr For user they dont know what they are doing ...
+
+ @seealso -
+
+ @param -
+ @return Current set lock mode.
+
+ @onerror No error should occure.
+ *//*-*****************************************************************************************************/
+ inline ELockMode getMode() const
+ {
+ return m_eMode;
+ }
//-------------------------------------------------------------------------------------------------------------
// private methods
@@ -156,11 +291,11 @@ class WriteGuard : private INonCopyAble
//-------------------------------------------------------------------------------------------------------------
private:
- IRWLock* m_pLock ; /// refrence to lock-member of protected object
+ IRWLock* m_pLock ; /// reference to lock-member of protected object
ELockMode m_eMode ; /// protection against multiple lock calls without unlock and difference between supported lock modi
}; // class WriteGuard
-} // namespace framework
+} // namespace framework
#endif // #ifndef __FRAMEWORK_THREADHELP_WRITEGUARD_HXX_