diff options
Diffstat (limited to 'framework/inc/threadhelp')
-rw-r--r-- | framework/inc/threadhelp/fairrwlock.hxx | 286 | ||||
-rw-r--r-- | framework/inc/threadhelp/gate.hxx | 248 | ||||
-rw-r--r-- | framework/inc/threadhelp/igate.h | 73 | ||||
-rw-r--r-- | framework/inc/threadhelp/imutex.h | 67 | ||||
-rw-r--r-- | framework/inc/threadhelp/inoncopyable.h | 77 | ||||
-rw-r--r-- | framework/inc/threadhelp/irwlock.h | 87 | ||||
-rw-r--r-- | framework/inc/threadhelp/itransactionmanager.h | 149 | ||||
-rw-r--r-- | framework/inc/threadhelp/lockhelper.hxx | 179 | ||||
-rw-r--r-- | framework/inc/threadhelp/readguard.hxx | 204 | ||||
-rw-r--r-- | framework/inc/threadhelp/resetableguard.hxx | 200 | ||||
-rw-r--r-- | framework/inc/threadhelp/threadhelpbase.hxx | 96 | ||||
-rw-r--r-- | framework/inc/threadhelp/transactionbase.hxx | 85 | ||||
-rw-r--r-- | framework/inc/threadhelp/transactionguard.hxx | 188 | ||||
-rw-r--r-- | framework/inc/threadhelp/transactionmanager.hxx | 118 | ||||
-rw-r--r-- | framework/inc/threadhelp/writeguard.hxx | 264 |
15 files changed, 2321 insertions, 0 deletions
diff --git a/framework/inc/threadhelp/fairrwlock.hxx b/framework/inc/threadhelp/fairrwlock.hxx new file mode 100644 index 000000000000..0f984c8d03f9 --- /dev/null +++ b/framework/inc/threadhelp/fairrwlock.hxx @@ -0,0 +1,286 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef __FRAMEWORK_THREADHELP_FAIRRWLOCK_HXX_ +#define __FRAMEWORK_THREADHELP_FAIRRWLOCK_HXX_ + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ + +#include <threadhelp/inoncopyable.h> +#include <threadhelp/irwlock.h> +#include <macros/debug.hxx> + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ +#include <com/sun/star/uno/XInterface.hpp> + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ +#include <osl/mutex.hxx> +#include <osl/conditn.hxx> + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ + +namespace framework{ + +//_________________________________________________________________________________________________________________ +// const +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// declarations +//_________________________________________________________________________________________________________________ + +/*-************************************************************************************************************//** + @short implement a read/write lock with fairness between read/write accessors + @descr These implementation never should used as base class! Use it as a member every time. + Use ReadGuard and/or WriteGuard in your methods (which work with these lock) + to make your code threadsafe. + Fair means: All reading or writing threads are synchronized AND serialzed by using one + mutex. For reader this mutex is used to access internal variables of this lock only; + for writer this mutex is used to have an exclusiv access on your class member! + => It's a multi-reader/single-writer lock, which no preferred accessor. + + @implements IRWlock + @base INonCopyable + IRWLock + + @devstatus ready to use +*//*-*************************************************************************************************************/ +class FairRWLock : public IRWLock + , private INonCopyable +{ + //------------------------------------------------------------------------------------------------------------- + // public methods + //------------------------------------------------------------------------------------------------------------- + public: + + /*-****************************************************************************************************//** + @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(); + } + + inline virtual ~FairRWLock() + { + } + + /*-****************************************************************************************************//** + @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 + //------------------------------------------------------------------------------------------------------------- + private: + + ::osl::Mutex m_aAccessLock ; /// regulate access on internal member of this instance + ::osl::Mutex m_aSerializer ; /// serialze incoming read/write access threads + ::osl::Condition m_aWriteCondition ; /// a writer must wait till current working reader are gone + sal_Int32 m_nReadCount ; /// every reader is registered - the last one open the door for waiting writer + +}; // class FairRWLock + +} // namespace framework + +#endif // #ifndef __FRAMEWORK_THREADHELP_FAIRRWLOCK_HXX_ diff --git a/framework/inc/threadhelp/gate.hxx b/framework/inc/threadhelp/gate.hxx new file mode 100644 index 000000000000..c3d4712d4fc9 --- /dev/null +++ b/framework/inc/threadhelp/gate.hxx @@ -0,0 +1,248 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef __FRAMEWORK_THREADHELP_GATE_HXX_ +#define __FRAMEWORK_THREADHELP_GATE_HXX_ + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ + +#include <threadhelp/inoncopyable.h> +#include <threadhelp/igate.h> + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ +#include <osl/mutex.hxx> +#include <osl/conditn.hxx> + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ + +namespace framework{ + +//_________________________________________________________________________________________________________________ +// const +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// declarations +//_________________________________________________________________________________________________________________ + +/*-************************************************************************************************************//** + @short implement a gate to block multiple threads at same time or unblock all + @descr A gate can be used as a negative-condition! You can open a "door" - wait() will not block ... + or you can close it - wait() blocks till open() is called again. + As a special feature you can open the gate a little bit by sing openGap(). + Then all currently waiting threads are running immediately - but new ones are blocked! + + @attention To prevent us against wrong using, the default ctor, copy ctor and the =operator are maked private! + + @implements IGate + @base IGate + INonCopyable + + @devstatus ready to use +*//*-*************************************************************************************************************/ +class Gate : public IGate + , private INonCopyable +{ + //------------------------------------------------------------------------------------------------------------- + // public methods + //------------------------------------------------------------------------------------------------------------- + public: + + /*-****************************************************************************************************//** + @short ctor + @descr These initialize the object right as an open gate. + + @seealso - + + @param - + @return - + + @onerror - + *//*-*****************************************************************************************************/ + inline Gate() + : m_bClosed ( sal_False ) + , m_bGapOpen ( sal_False ) + { + open(); + } + + /*-****************************************************************************************************//** + @short dtor + @descr Is user forget it - we open the gate ... + blocked threads can running ... but I don't know + if it's right - we are destroyed yet!? + + @seealso - + + @param - + @return - + + @onerror - + *//*-*****************************************************************************************************/ + inline virtual ~Gate() + { + open(); + } + + /*-****************************************************************************************************//** + @interface IGate + @short open the gate + @descr A wait() call will not block then. + + @seealso method close() + + @param - + @return - + + @onerror - + *//*-*****************************************************************************************************/ + 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. + + @seealso method open() + + @param - + @return - + + @onerror - + *//*-*****************************************************************************************************/ + 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. + The "gap" is closed by any new thread which call wait() automaticly! + + @seealso method wait() + @seealso method open() + + @param - + @return - + + @onerror - + *//*-*****************************************************************************************************/ + 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. + If gap "open" => currently waiting threads unblocked, new ones blocked + + @seealso method wait() + @seealso method open() + + @param "pTimeOut", optional parameter to wait a certain time + @return true, if wait was successful (gate was opened) + false, if condition has an error or timeout was reached! + + @onerror We return false. + *//*-*****************************************************************************************************/ + 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::Condition::result_ok ); + } + + return bSuccessful; + } + + //------------------------------------------------------------------------------------------------------------- + // private member + //------------------------------------------------------------------------------------------------------------- + private: + + ::osl::Mutex m_aAccessLock ; + ::osl::Condition m_aPassage ; + sal_Bool m_bClosed ; + sal_Bool m_bGapOpen ; + +}; // class Gate + +} // namespace framework + +#endif // #ifndef __FRAMEWORK_THREADHELP_GATE_HXX_ diff --git a/framework/inc/threadhelp/igate.h b/framework/inc/threadhelp/igate.h new file mode 100644 index 000000000000..b599dcd4ac25 --- /dev/null +++ b/framework/inc/threadhelp/igate.h @@ -0,0 +1,73 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef __FRAMEWORK_THREADHELP_IGATE_H_ +#define __FRAMEWORK_THREADHELP_IGATE_H_ + +//_________________________________________________________________________________________________________________ +// includes +//_________________________________________________________________________________________________________________ + +#include <osl/time.h> + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ + +namespace framework{ + +//_________________________________________________________________________________________________________________ +// declarations +//_________________________________________________________________________________________________________________ + +/*-************************************************************************************************************//** + @descr We need this interface to support using of different gate implementations in a generic way. +*//*-*************************************************************************************************************/ +class IGate +{ + //------------------------------------------------------------------------------------------------------------- + // public methods + //------------------------------------------------------------------------------------------------------------- + public: + + /*-****************************************************************************************************//** + @descr These functions must be supported by a derived class! + open() -open access for all waiting threads + close() -close access for all further coming threads + openGap() -open access for current waiting threads only + wait() -must be called to pass the gate + *//*-*****************************************************************************************************/ + virtual void open ( ) = 0; + virtual void close ( ) = 0; + virtual void openGap ( ) = 0; + virtual sal_Bool wait ( const TimeValue* pTimeOut = NULL ) = 0; + +}; // class IGate + +} // namespace framework + +#endif // #ifndef __FRAMEWORK_THREADHELP_IGATE_H_ diff --git a/framework/inc/threadhelp/imutex.h b/framework/inc/threadhelp/imutex.h new file mode 100644 index 000000000000..70784c312b87 --- /dev/null +++ b/framework/inc/threadhelp/imutex.h @@ -0,0 +1,67 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef __FRAMEWORK_THREADHELP_IMUTEX_H_ +#define __FRAMEWORK_THREADHELP_IMUTEX_H_ + +//_________________________________________________________________________________________________________________ +// includes +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ + +namespace framework{ + +//_________________________________________________________________________________________________________________ +// declarations +//_________________________________________________________________________________________________________________ + +/*-************************************************************************************************************//** + @descr We need this interface to support using of different mutex implementations in a generic way. +*//*-*************************************************************************************************************/ +class IMutex +{ + //------------------------------------------------------------------------------------------------------------- + // public methods + //------------------------------------------------------------------------------------------------------------- + public: + + /*-****************************************************************************************************//** + @descr These functions must be supported by a derived class! + acquire() -try to register thread + release() -unregister thread + *//*-*****************************************************************************************************/ + virtual void acquire() = 0; + virtual void release() = 0; + +}; // class IMutex + +} // namespace framework + +#endif // #ifndef __FRAMEWORK_THREADHELP_IMUTEX_H_ diff --git a/framework/inc/threadhelp/inoncopyable.h b/framework/inc/threadhelp/inoncopyable.h new file mode 100644 index 000000000000..a0652ff2ea39 --- /dev/null +++ b/framework/inc/threadhelp/inoncopyable.h @@ -0,0 +1,77 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef __FRAMEWORK_THREADHELP_INONCOPYABLE_H_ +#define __FRAMEWORK_THREADHELP_INONCOPYABLE_H_ + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ + +namespace framework{ + +//_________________________________________________________________________________________________________________ +// const +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// declarations +//_________________________________________________________________________________________________________________ + +/*-************************************************************************************************************//** + @descr Use this as one of your base classes to disable + all possiblities to copy or assign one object to another one! + We declare neccessary functions private to do so. +*//*-*************************************************************************************************************/ +class INonCopyable +{ + public: + + INonCopyable() {} + + private: + + INonCopyable ( const INonCopyable& rCopy ); + INonCopyable& operator= ( const INonCopyable& rCopy ); + +}; // class INonCopyable + +} // namespace framework + +#endif // #ifndef __FRAMEWORK_THREADHELP_INONCOPYABLE_H_ diff --git a/framework/inc/threadhelp/irwlock.h b/framework/inc/threadhelp/irwlock.h new file mode 100644 index 000000000000..e34b310a8fe8 --- /dev/null +++ b/framework/inc/threadhelp/irwlock.h @@ -0,0 +1,87 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef __FRAMEWORK_THREADHELP_IRWLOCK_H_ +#define __FRAMEWORK_THREADHELP_IRWLOCK_H_ + +//_________________________________________________________________________________________________________________ +// includes +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ + +namespace framework{ + +//_________________________________________________________________________________________________________________ +// declarations +//_________________________________________________________________________________________________________________ + +/*-************************************************************************************************************//** + @descr A guard (specialy a write guard) support different internal working states. + His lock can set for reading or writing/reading! Or he was unlocked by user ... +*//*-*************************************************************************************************************/ +enum ELockMode +{ + E_NOLOCK , + E_READLOCK , + E_WRITELOCK +}; + +/*-************************************************************************************************************//** + @descr We implement two guards for using an rw-lock. But if you wish to implement + different rw-locks to you will have problems by using with same guard implementation! + Thats why we define this "pure virtual base class" ... + All rw-locks must support this base interface for working and all guard must use this one too! +*//*-*************************************************************************************************************/ +class IRWLock +{ + //------------------------------------------------------------------------------------------------------------- + // public methods + //------------------------------------------------------------------------------------------------------------- + public: + + /*-****************************************************************************************************//** + @descr These functions must be supported by a derived class! + acquireReadAccess() -try to register thread as reader + releaseReadAccess() -unregister thread as reader + acquireWriteAccess() -try to register thread as writer + releaseWriteAccess() -unregister thread as writer + downgradeWriteAccess() -make writer to reader + *//*-*****************************************************************************************************/ + virtual void acquireReadAccess () =0; + virtual void releaseReadAccess () =0; + virtual void acquireWriteAccess () =0; + virtual void releaseWriteAccess () =0; + virtual void downgradeWriteAccess () =0; + +}; // class IRWLock + +} // namespace framework + +#endif // #ifndef __FRAMEWORK_THREADHELP_IRWLOCK_H_ diff --git a/framework/inc/threadhelp/itransactionmanager.h b/framework/inc/threadhelp/itransactionmanager.h new file mode 100644 index 000000000000..f0db5a24a113 --- /dev/null +++ b/framework/inc/threadhelp/itransactionmanager.h @@ -0,0 +1,149 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef __FRAMEWORK_THREADHELP_ITRANSACTIONMANAGER_H_ +#define __FRAMEWORK_THREADHELP_ITRANSACTIONMANAGER_H_ + +//_________________________________________________________________________________________________________________ +// includes +//_________________________________________________________________________________________________________________ + +#include <general.h> +#include <com/sun/star/uno/RuntimeException.hpp> +#include <com/sun/star/lang/DisposedException.hpp> + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ + +namespace framework{ + +//_________________________________________________________________________________________________________________ +// declarations +//_________________________________________________________________________________________________________________ + +/*-************************************************************************************************************//** + @descr Describe different states of a feature of following implementation. + During live time of an object different working states occure: + initialization - working - closing - closed + If you whish to implement thread safe classes you should use these feature to protect + your code against calls at wrong time. e.g. you are not full initialized but somewhere + call an interface method (initialize phase means startup time from creating object till + calling specified first method e.g. XInitialization::initialze()!) then you should refuse + this call. The same for closing/disposing the object! +*//*-*************************************************************************************************************/ +enum EWorkingMode +{ + E_INIT , // We stand in a init method -> some calls are accepted - some one are rejected + E_WORK , // Object is ready for working -> all calls are accepted + E_BEFORECLOSE, // We stand in a close method -> some calls are accepted - some one are rejected + E_CLOSE // Object is dead! -> all calls are rejected! +}; + +/*-************************************************************************************************************//** + @descr If a request was refused by a transaction manager (internal state different E_WORK ...) + user can check the reason by using this enum values. +*//*-*************************************************************************************************************/ +enum ERejectReason +{ + E_UNINITIALIZED , + E_NOREASON , + E_INCLOSE , + E_CLOSED +}; + +/*-************************************************************************************************************//** + @descr A transaction object should support throwing exceptions if user used it at wrong working mode. + e.g. We can throw a DisposedException if user try to work and our mode is E_CLOSE! + But sometimes he dont need this feature - will handle it by himself. + Then we must differ between some exception-modi: + E_NOEXCEPTIONS We never throw any exceptions! User handle it private and looks for ERejectReason. + E_HARDEXCEPTIONS We throw exceptions for all working modes different from E_WORK! + E_SOFTEXCEPTIONS We throw exceptions for all working modes different from E_WORK AND E_INCLOSE! + This mode is useful for impl-methods which should be callable from dispose() method! + + e.g. void dispose() + { + m_aTransactionManager.setWorkingMode( E_BEFORECLOSE ); + ... + impl_setA( 0 ); + ... + m_aTransactionManager.setWorkingMode( E_CLOSE ); + } + + void impl_setA( int nA ) + { + ERejectReason EReason; + TransactionGuard aTransactionGuard( m_aTransactionManager, E_SOFTEXCEPTIONS, eReason ); + + m_nA = nA; + } + + Normaly (if E_HARDEXCEPTIONS was used!) creation of guard + will throw an exception ... but using of E_SOFTEXCEPTIONS suppress it + and member "A" can be set. +*//*-*************************************************************************************************************/ +enum EExceptionMode +{ + E_NOEXCEPTIONS , + E_HARDEXCEPTIONS, + E_SOFTEXCEPTIONS +}; + +/*-************************************************************************************************************//** + @descr How can you use the transaction manager? + Use it in combination with an TransactionGuard, which register your transaction in ctor + and release in dtor automaticly! Follow interface class can be used to make using + of different manager implmentations possible by using same guard. +*//*-*************************************************************************************************************/ +class ITransactionManager +{ + //------------------------------------------------------------------------------------------------------------- + // public methods + //------------------------------------------------------------------------------------------------------------- + public: + + /*-****************************************************************************************************//** + @descr These functions must be supported by a derived class! + getWorkingMode() -return current set working mode + setWorkingMode() -change working mode + (This will block till all current transactions are finished!) + isCallRejected() -test method to check if a call will be rejected by wrong working mode or not + registerTransaction() -start new transaction (increase internal transaction count) + unregisterTransaction() -finish transaction (decrease internal transaction count) + *//*-*****************************************************************************************************/ + virtual EWorkingMode getWorkingMode ( ) const = 0; + virtual void setWorkingMode ( EWorkingMode eMode ) = 0; + virtual sal_Bool isCallRejected ( ERejectReason& eReason ) const = 0; + virtual void registerTransaction ( EExceptionMode eMode , ERejectReason& eReason ) throw( css::uno::RuntimeException, css::lang::DisposedException ) = 0; + virtual void unregisterTransaction ( ) throw( css::uno::RuntimeException, css::lang::DisposedException ) = 0; + +}; // class ITransactionManager + +} // namespace framework + +#endif // #ifndef __FRAMEWORK_THREADHELP_ITRANSACTIONMANAGER_H_ diff --git a/framework/inc/threadhelp/lockhelper.hxx b/framework/inc/threadhelp/lockhelper.hxx new file mode 100644 index 000000000000..5677350b5349 --- /dev/null +++ b/framework/inc/threadhelp/lockhelper.hxx @@ -0,0 +1,179 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef __FRAMEWORK_THREADHELP_LOCKHELPER_HXX_ +#define __FRAMEWORK_THREADHELP_LOCKHELPER_HXX_ + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ + +#include <threadhelp/inoncopyable.h> +#include <threadhelp/imutex.h> +#include <threadhelp/irwlock.h> +#include <threadhelp/fairrwlock.hxx> + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ +#include <osl/mutex.hxx> +#include <vos/mutex.hxx> + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ + +namespace framework{ + +//_________________________________________________________________________________________________________________ +// const +//_________________________________________________________________________________________________________________ + +/*-************************************************************************************************************//** + @descr If you use a lock or mutex as a member of your class and whish to use it earlier then other ones + you should have a look on this implementation. You must use it as the first base class + of your implementation - because base classes are initialized by his order and before your + member! Thats why ist a good place to declare your thread help member so. +*//*-*************************************************************************************************************/ +enum ELockType +{ + E_NOTHING = 0 , + E_OWNMUTEX = 1 , + E_SOLARMUTEX = 2 , + E_FAIRRWLOCK = 3 +}; + +#define ENVVAR_LOCKTYPE DECLARE_ASCII("LOCKTYPE_FRAMEWORK") +#define FALLBACK_LOCKTYPE E_SOLARMUTEX + +//_________________________________________________________________________________________________________________ +// declarations +//_________________________________________________________________________________________________________________ + +/*-************************************************************************************************************//** + @short helper to set right lock in right situation + @descr This helper support different types of locking: + a) no locks - transparent for user! + This could be usefull for simluation or single threaded environments! + b) own mutex + An object use his own osl-mutex to be threadsafe. Usefull for easy and exclusiv locking. + c) solar mutex + An object use our solar mutex and will be a part of a greater safed "threadsafe code block". + Could be usefull for simulation and testing of higher modules! + d) fair rw-lock + An object use an implementation of a fair rw-lock. This increase granularity of t hreadsafe mechanism + and should be used for high performance threadsafe code! + + @attention We support two interfaces - "IMutex" and "IRWLock". Don't mix using of it! + A guard implementation should use one interface only! + + @implements IMutex + @implements IRWLock + + @base INonCopyable + IMutex + IRWLock + + @devstatus draft +*//*-*************************************************************************************************************/ +class LockHelper : public IMutex + , public IRWLock + , private INonCopyable +{ + //------------------------------------------------------------------------------------------------------------- + // public methods + //------------------------------------------------------------------------------------------------------------- + public: + + //------------------------------------------------------------------------------------------------------------- + // ctor/dtor + //------------------------------------------------------------------------------------------------------------- + LockHelper( ::vos::IMutex* pSolarMutex = NULL ); + virtual ~LockHelper( ); + + //------------------------------------------------------------------------------------------------------------- + // interface ::framework::IMutex + //------------------------------------------------------------------------------------------------------------- + virtual void acquire(); + virtual void release(); + + //------------------------------------------------------------------------------------------------------------- + // interface ::framework::IRWLock + //------------------------------------------------------------------------------------------------------------- + virtual void acquireReadAccess (); + virtual void releaseReadAccess (); + virtual void acquireWriteAccess (); + virtual void releaseWriteAccess (); + virtual void downgradeWriteAccess(); + + //------------------------------------------------------------------------------------------------------------- + // something else + //------------------------------------------------------------------------------------------------------------- + static LockHelper& getGlobalLock ( ::vos::IMutex* pSolarMutex = NULL ); + ::osl::Mutex& getShareableOslMutex( ); + + //------------------------------------------------------------------------------------------------------------- + // private methods + //------------------------------------------------------------------------------------------------------------- + private: + + static ELockType& implts_getLockType(); + + //------------------------------------------------------------------------------------------------------------- + // private member + // a) Make some member mutable for using in const functions! + // b) "m_eLockType" define, which of follow members is used! + // You can use "m_pFairRWLock" as a fair rw-lock (multiple reader / one writer / looks for incoming order of threads too) ... + // or you can use a normal osl mutex ("m_pOwnMutex") ... + // ... or the solarmuex as "m_pSolarMutex" (must be set from outside! because some components must be vcl-free!) + // ... but sometimes you need a shareable osl mutex! + // In this case you has some problems: i ) If your lock type is set to E_OWNMUTEX => it's easy; you can use your member "m_pOwnMutex" - it's a osl mutex. + // Creation and using of "m_pShareableOslMutex" isn't neccessary! + // ii ) Otherwise you have no osl mutex ... so you must create "m_pShareableOslMutex" and use it twice! + // In this case you must lock two member everytime - "m_pShareableMutex" AND "m_pFairRWLock" or "m_pSolarMutex" or ... + // It isn't realy fine - but the only possible way. + // iii) There exist another special case - E_NOTHING is set! Then we should create this shareable mutex ... + // nad you can use it ... but this implmentation ignore it. + //------------------------------------------------------------------------------------------------------------- + private: + + ELockType m_eLockType ; + + mutable FairRWLock* m_pFairRWLock ; + mutable ::osl::Mutex* m_pOwnMutex ; + mutable ::vos::IMutex* m_pSolarMutex ; + mutable ::osl::Mutex* m_pShareableOslMutex ; + mutable sal_Bool m_bDummySolarMutex ; +}; + +} // namespace framework + +#endif // #ifndef __FRAMEWORK_THREADHELP_LOCKHELPER_HXX_ diff --git a/framework/inc/threadhelp/readguard.hxx b/framework/inc/threadhelp/readguard.hxx new file mode 100644 index 000000000000..997042c9e601 --- /dev/null +++ b/framework/inc/threadhelp/readguard.hxx @@ -0,0 +1,204 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef __FRAMEWORK_THREADHELP_READGUARD_HXX_ +#define __FRAMEWORK_THREADHELP_READGUARD_HXX_ + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ + +#include <threadhelp/inoncopyable.h> +#include <threadhelp/irwlock.h> + +//#ifndef __FRAMEWORK_THREADHELP_THREADHELPBASE_HXX_ +//#include <threadhelp/threadhelpbase.hxx> +//#endif + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ +#include <sal/types.h> + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ + +namespace framework{ + +//_________________________________________________________________________________________________________________ +// const +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// declarations +//_________________________________________________________________________________________________________________ + +/*-************************************************************************************************************//** + @short implement a guard to set read locks + @descr This guard should be used to set a lock for reading object internal member. + Nobody can control it but don't use member after successfuly locking for writing! + 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 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 + + @devstatus ready to use +*//*-*************************************************************************************************************/ +class ReadGuard : private INonCopyable +{ + //------------------------------------------------------------------------------------------------------------- + // public methods + //------------------------------------------------------------------------------------------------------------- + public: + + /*-****************************************************************************************************//** + @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 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 + //------------------------------------------------------------------------------------------------------------- + private: + + /*-****************************************************************************************************//** + @short disable using of these functions! + @descr It's not allowed to use this methods. Different problem can occure otherwise. + Thats why we disable it by make it private. + + @seealso other ctor + + @param - + @return - + + @onerror - + *//*-*****************************************************************************************************/ + ReadGuard(); + + //------------------------------------------------------------------------------------------------------------- + // private member + //------------------------------------------------------------------------------------------------------------- + private: + + IRWLock* m_pLock ; /// reference to lock-member of protected object + sal_Bool m_bLocked ; /// protection against multiple lock calls without unlock! + +}; // class ReadGuard + +} // namespace framework + +#endif // #ifndef __FRAMEWORK_THREADHELP_READGUARD_HXX_ diff --git a/framework/inc/threadhelp/resetableguard.hxx b/framework/inc/threadhelp/resetableguard.hxx new file mode 100644 index 000000000000..58830189e052 --- /dev/null +++ b/framework/inc/threadhelp/resetableguard.hxx @@ -0,0 +1,200 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef __FRAMEWORK_THREADHELP_RESETABLEGUARD_HXX_ +#define __FRAMEWORK_THREADHELP_RESETABLEGUARD_HXX_ + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ + +#include <threadhelp/inoncopyable.h> +#include <threadhelp/imutex.h> + +//#ifndef __FRAMEWORK_THREADHELP_THREADHELPBASE_HXX_ +//#include <threadhelp/threadhelpbase.hxx> +//#endif + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ +#include <sal/types.h> + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ + +namespace framework{ + +//_________________________________________________________________________________________________________________ +// const +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// declarations +//_________________________________________________________________________________________________________________ + +/*-************************************************************************************************************//** + @short implement a guard for implementing save thread access + @descr These guard has an additional feature to well known one ::osl::Guard. + You can lock() and unlock() it very often! + 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 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 + + @devstatus ready to use +*//*-*************************************************************************************************************/ +class ResetableGuard : private INonCopyable +{ + //------------------------------------------------------------------------------------------------------------- + // public methods + //------------------------------------------------------------------------------------------------------------- + public: + + /*-****************************************************************************************************//** + @short ctors + @descr Use these ctor methods to initialize the guard right. + Given lock reference must be valid - otherwise crashes could occure! + + @seealso - + + @param "pLock", pointer to lock helper of user + @param "rLock", reference to lock helper of user + @return - + + @onerror - + *//*-*****************************************************************************************************/ + 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 + @descr We must release set mutex if programmer forget it ... + + @seealso - + + @param - + @return - + + @onerror - + *//*-*****************************************************************************************************/ + 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 + 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! + It will be a function-local object every time. + + @seealso - + + @param - + @return - + + @onerror - + *//*-*****************************************************************************************************/ + 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 + //------------------------------------------------------------------------------------------------------------- + private: + + /*-****************************************************************************************************//** + @short disable using of these functions! + @descr It's not allowed to use this methods. Different problem can occure otherwise. + Thats why we disable it by make it private. + + @seealso other ctor + + @param - + @return - + + @onerror - + *//*-*****************************************************************************************************/ + ResetableGuard(); + + //------------------------------------------------------------------------------------------------------------- + // private member + //------------------------------------------------------------------------------------------------------------- + private: + + IMutex* m_pLock ; /// pointer to safed lock member of user + sal_Bool m_bLocked ; /// protection against multiple lock() calls without unlock() + +}; // class ResetableGuard + +} // namespace framework + +#endif // #ifndef __FRAMEWORK_THREADHELP_RESETABLEGUARD_HXX_ diff --git a/framework/inc/threadhelp/threadhelpbase.hxx b/framework/inc/threadhelp/threadhelpbase.hxx new file mode 100644 index 000000000000..499d6324d6ca --- /dev/null +++ b/framework/inc/threadhelp/threadhelpbase.hxx @@ -0,0 +1,96 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef __FRAMEWORK_THREADHELP_THREADHELPBASE_HXX_ +#define __FRAMEWORK_THREADHELP_THREADHELPBASE_HXX_ + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ + +#include <threadhelp/lockhelper.hxx> + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ + +namespace framework{ + +//_________________________________________________________________________________________________________________ +// const +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// declarations +//_________________________________________________________________________________________________________________ + +/*-************************************************************************************************************//** + @short "baseclass" to make own classes threadsafe + @descr Sometimes you must share your lock- or mutex member with any other baseclasses. + And baseclasses are initialized erlier then members! That's why you should use + this struct as first of your baseclasses!!! + Then you will get a public member "m_aLock" which can be used by special guard implementations + to make your code threadsafe. + + @seealso class LockHelper + + @implements - + @base - + + @devstatus ready to use +*//*-*************************************************************************************************************/ +struct ThreadHelpBase +{ + //------------------------------------------------------------------------------------------------------------- + // public methods + //------------------------------------------------------------------------------------------------------------- + public: + ThreadHelpBase( ::vos::IMutex* pSolarMutex = NULL ) + : m_aLock( pSolarMutex ) + { + } + + //------------------------------------------------------------------------------------------------------------- + // public member + // Make it mutable for using in const functions! + //------------------------------------------------------------------------------------------------------------- + public: + + mutable LockHelper m_aLock; +}; + +} // namespace framework + +#endif // #ifndef __FRAMEWORK_THREADHELP_THREADHELPBASE_HXX_ diff --git a/framework/inc/threadhelp/transactionbase.hxx b/framework/inc/threadhelp/transactionbase.hxx new file mode 100644 index 000000000000..7cb0eba2eb61 --- /dev/null +++ b/framework/inc/threadhelp/transactionbase.hxx @@ -0,0 +1,85 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef __FRAMEWORK_THREADHELP_TRANSACTIONBASE_H_ +#define __FRAMEWORK_THREADHELP_TRANSACTIONBASE_H_ + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ + +#include <threadhelp/transactionmanager.hxx> + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ + +namespace framework{ + +//_________________________________________________________________________________________________________________ +// const +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// declarations +//_________________________________________________________________________________________________________________ + +/*-************************************************************************************************************//** + @short make it possible to instanciate a transacion manager as first member! + @descr If you use a transaction manager as a member of your class and whish to use it earlier then other ones + you should have a look on this implementation. You must use it as the first base class + of your implementation - because base classes are initialized by his order and before your + member! Thats why ist a good place to declare this member. + + @implements - + @base - + + @devstatus ready to use +*//*-*************************************************************************************************************/ +struct TransactionBase +{ + //------------------------------------------------------------------------------------------------------------- + // public member + //------------------------------------------------------------------------------------------------------------- + public: + + mutable TransactionManager m_aTransactionManager ; /// "your" public manager-member! + /// Make it mutable for using in const functions! + +}; // struct TransactionBase + +} // namespace framework + +#endif // #ifndef __FRAMEWORK_THREADHELP_TRANSACTIONBASE_H_ diff --git a/framework/inc/threadhelp/transactionguard.hxx b/framework/inc/threadhelp/transactionguard.hxx new file mode 100644 index 000000000000..e116cf8a2185 --- /dev/null +++ b/framework/inc/threadhelp/transactionguard.hxx @@ -0,0 +1,188 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef __FRAMEWORK_THREADHELP_TRANSACTIONGUARD_HXX_ +#define __FRAMEWORK_THREADHELP_TRANSACTIONGUARD_HXX_ + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ + +#include <threadhelp/inoncopyable.h> +#include <threadhelp/itransactionmanager.h> + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ + +namespace framework{ + +//_________________________________________________________________________________________________________________ +// const +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// declarations +//_________________________________________________________________________________________________________________ + +/*-************************************************************************************************************//** + @short implement a guard to support non breakable transactions + @descr If you whish to support non breakable method calls without lockingf any mutex, rw-lock or + something like that - you should use this guard implementation. + Initialize it at first in your method and don't release it till end of your function! + Your "transaction" is registered in ctor and automaticly released in dtor. + Use set/get of working mode to enable/disable further transactions. + It's possible too, to enable automaticly throwing of some exceptions for illegal + transaction requests ... e.g. interface call for already disposed objects. + + @attention To prevent us against wrong using, the default ctor, copy ctor and the =operator are maked private! + + @implements - + @base INonCopyable + + @devstatus draft +*//*-*************************************************************************************************************/ +class TransactionGuard : private INonCopyable +{ + //------------------------------------------------------------------------------------------------------------- + // public methods + //------------------------------------------------------------------------------------------------------------- + public: + + /*-****************************************************************************************************//** + @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 + //------------------------------------------------------------------------------------------------------------- + private: + + /*-****************************************************************************************************//** + @short disable using of these functions! + @descr It's not allowed to use this methods. Different problem can occure otherwise. + Thats why we disable it by make it private. + + @seealso other ctor + + @param - + @return - + + @onerror - + *//*-*****************************************************************************************************/ + TransactionGuard(); + + //------------------------------------------------------------------------------------------------------------- + // private member + //------------------------------------------------------------------------------------------------------------- + private: + + ITransactionManager* m_pManager ; /// pointer to safed transaction manager + +}; // class TransactionGuard + +} // namespace framework + +#endif // #ifndef __FRAMEWORK_THREADHELP_TRANSACTIONGUARD_HXX_ diff --git a/framework/inc/threadhelp/transactionmanager.hxx b/framework/inc/threadhelp/transactionmanager.hxx new file mode 100644 index 000000000000..eca13d63103c --- /dev/null +++ b/framework/inc/threadhelp/transactionmanager.hxx @@ -0,0 +1,118 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef __FRAMEWORK_THREADHELP_TRANSACTIONMANAGER_HXX_ +#define __FRAMEWORK_THREADHELP_TRANSACTIONMANAGER_HXX_ + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ + +#include <threadhelp/inoncopyable.h> +#include <threadhelp/itransactionmanager.h> +#include <threadhelp/gate.hxx> +#include <macros/debug.hxx> + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/uno/XInterface.hpp> +#include <com/sun/star/uno/RuntimeException.hpp> +#include <com/sun/star/lang/DisposedException.hpp> + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ +#include <osl/mutex.hxx> + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ + +namespace framework{ + +//_________________________________________________________________________________________________________________ +// const +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// declarations +//_________________________________________________________________________________________________________________ + +/*-************************************************************************************************************//** + @short implement a transaction manager to support non breakable interface methods + @descr Use it to support non breakable interface methods without using any thread + synchronization like e.g. mutex, rw-lock! + That protect your code against wrong calls at wrong time ... e.g. calls after disposing an object! + Use combination of EExceptionMode and ERejectReason to detect rejected requests + and react for it. You can enable automaticly throwing of exceptions too. + + @implements ITransactionManager + @base INonCopyable + ITransactionManager + + @devstatus draft +*//*-*************************************************************************************************************/ +class TransactionManager : public ITransactionManager + , private INonCopyable +{ + //------------------------------------------------------------------------------------------------------------- + // public methods + //------------------------------------------------------------------------------------------------------------- + public: + + TransactionManager ( ); + virtual ~TransactionManager ( ); + virtual void setWorkingMode ( EWorkingMode eMode ); + virtual EWorkingMode getWorkingMode ( ) const; + virtual sal_Bool isCallRejected ( ERejectReason& eReason ) const; + virtual void registerTransaction ( EExceptionMode eMode, ERejectReason& eReason ) throw( css::uno::RuntimeException, css::lang::DisposedException ); + virtual void unregisterTransaction ( ) throw( css::uno::RuntimeException, css::lang::DisposedException ); + + //------------------------------------------------------------------------------------------------------------- + // private methods + //------------------------------------------------------------------------------------------------------------- + private: + + void impl_throwExceptions( EExceptionMode eMode, ERejectReason eReason ) const throw( css::uno::RuntimeException, css::lang::DisposedException ); + + //------------------------------------------------------------------------------------------------------------- + // private member + //------------------------------------------------------------------------------------------------------------- + private: + + mutable ::osl::Mutex m_aAccessLock ; /// regulate access on internal member of this instance + Gate m_aBarrier ; /// used to block transactions requests during change or work mode + EWorkingMode m_eWorkingMode ; /// current working mode of object which use this manager (used to reject calls at wrong time) + sal_Int32 m_nTransactionCount ; /// every transaction request is registered by this counter + +}; // class TransactionManager + +} // namespace framework + +#endif // #ifndef __FRAMEWORK_THREADHELP_TRANSACTIONMANAGER_HXX_ diff --git a/framework/inc/threadhelp/writeguard.hxx b/framework/inc/threadhelp/writeguard.hxx new file mode 100644 index 000000000000..07dbdf6fe466 --- /dev/null +++ b/framework/inc/threadhelp/writeguard.hxx @@ -0,0 +1,264 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef __FRAMEWORK_THREADHELP_WRITEGUARD_HXX_ +#define __FRAMEWORK_THREADHELP_WRITEGUARD_HXX_ + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ + +#include <threadhelp/inoncopyable.h> +#include <threadhelp/irwlock.h> + +//#ifndef __FRAMEWORK_THREADHELP_THREADHELPBASE_HXX_ +//#include <threadhelp/threadhelpbase.hxx> +//#endif + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ + +namespace framework{ + +//_________________________________________________________________________________________________________________ +// const +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// declarations +//_________________________________________________________________________________________________________________ + +/*-************************************************************************************************************//** + @short implement a guard to set write locks + @descr This guard should be used to set a lock for reading AND writing object internal member. + 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 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 + + @devstatus ready to use +*//*-*************************************************************************************************************/ +class WriteGuard : private INonCopyable +{ + //------------------------------------------------------------------------------------------------------------- + // public methods + //------------------------------------------------------------------------------------------------------------- + public: + + /*-****************************************************************************************************//** + @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; + default: break; // nothing to do + } + } + + /*-****************************************************************************************************//** + @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; + default: break; // nothing to do + } + } + + /*-****************************************************************************************************//** + @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 + //------------------------------------------------------------------------------------------------------------- + private: + + /*-****************************************************************************************************//** + @short disable using of these functions! + @descr It's not allowed to use this methods. Different problem can occure otherwise. + Thats why we disable it by make it private. + + @seealso other ctor + + @param - + @return - + + @onerror - + *//*-*****************************************************************************************************/ + WriteGuard(); + + //------------------------------------------------------------------------------------------------------------- + // private member + //------------------------------------------------------------------------------------------------------------- + private: + + 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 + +#endif // #ifndef __FRAMEWORK_THREADHELP_WRITEGUARD_HXX_ |