diff options
Diffstat (limited to 'tqtinterface/qt4/src/tools/tqmutex_unix.cpp')
-rw-r--r-- | tqtinterface/qt4/src/tools/tqmutex_unix.cpp | 695 |
1 files changed, 0 insertions, 695 deletions
diff --git a/tqtinterface/qt4/src/tools/tqmutex_unix.cpp b/tqtinterface/qt4/src/tools/tqmutex_unix.cpp deleted file mode 100644 index 540a128..0000000 --- a/tqtinterface/qt4/src/tools/tqmutex_unix.cpp +++ /dev/null @@ -1,695 +0,0 @@ -/**************************************************************************** -** -** TQMutex class for Unix -** -** Created : 20010725 -** -** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA. -** -** This file is part of the tools module of the TQt GUI Toolkit. -** -** This file may be used under the terms of the GNU General -** Public License versions 2.0 or 3.0 as published by the Free -** Software Foundation and appearing in the files LICENSE.GPL2 -** and LICENSE.GPL3 included in the packaging of this file. -** Alternatively you may (at your option) use any later version -** of the GNU General Public License if such license has been -** publicly approved by Trolltech ASA (or its successors, if any) -** and the KDE Free TQt Foundation. -** -** Please review the following information to ensure GNU General -** Public Licensing requirements will be met: -** http://trolltech.com/products/qt/licenses/licensing/opensource/. -** If you are unsure which license is appropriate for your use, please -** review the following information: -** http://trolltech.com/products/qt/licenses/licensing/licensingoverview -** or contact the sales department at sales@trolltech.com. -** -** This file may be used under the terms of the Q Public License as -** defined by Trolltech ASA and appearing in the file LICENSE.TQPL -** included in the packaging of this file. Licensees holding valid TQt -** Commercial licenses may use this file in accordance with the TQt -** Commercial License Agreement provided with the Software. -** -** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, -** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted -** herein. -** -**********************************************************************/ - -#if defined(TQT_THREAD_SUPPORT) - -#include "tqplatformdefs.h" - -typedef pthread_mutex_t TQ_MUTEX_T; - -// POSIX threads mutex types -#if ((defined(PTHREAD_MUTEX_RECURSIVE) && defined(PTHREAD_MUTEX_DEFAULT)) || \ - defined(TQ_OS_FREEBSD)) && !defined(TQ_OS_UNIXWARE) && !defined(TQ_OS_SOLARIS) && \ - !defined(TQ_OS_MAC) -// POSIX 1003.1c-1995 - We love this OS -# define TQ_MUTEX_SET_TYPE(a, b) pthread_mutexattr_settype((a), (b)) -# if defined(TQT_CHECK_RANGE) -# define TQ_NORMAL_MUTEX_TYPE PTHREAD_MUTEX_ERRORCHECK -# else -# define TQ_NORMAL_MUTEX_TYPE PTHREAD_MUTEX_DEFAULT -# endif -# define TQ_RECURSIVE_MUTEX_TYPE PTHREAD_MUTEX_RECURSIVE -#elif defined(MUTEX_NONRECURSIVE_NP) && defined(MUTEX_RECURSIVE_NP) -// POSIX 1003.4a pthreads draft extensions -# define TQ_MUTEX_SET_TYPE(a, b) pthread_mutexattr_setkind_np((a), (b)); -# define TQ_NORMAL_MUTEX_TYPE MUTEX_NONRECURSIVE_NP -# define TQ_RECURSIVE_MUTEX_TYPE MUTEX_RECURSIVE_NP -#else -// Unknown mutex types - skip them -# define TQ_MUTEX_SET_TYPE(a, b) -# undef TQ_NORMAL_MUTEX_TYPE -# undef TQ_RECURSIVE_MUTEX_TYPE -#endif - -#include "tqmutex.h" -#include "tqmutex_p.h" - -#include <errno.h> -#include <string.h> - - -// Private class declarations - -class TQRealMutexPrivate : public TQMutexPrivate { -public: - TQRealMutexPrivate(bool = FALSE); - - void lock(); - void unlock(); - bool locked(); - bool trylock(); - int type() const; - - bool recursive; -}; - -#ifndef TQ_RECURSIVE_MUTEX_TYPE -class TQRecursiveMutexPrivate : public TQMutexPrivate -{ -public: - TQRecursiveMutexPrivate(); - ~TQRecursiveMutexPrivate(); - - void lock(); - void unlock(); - bool locked(); - bool trylock(); - int type() const; - - int count; - unsigned long owner; - pthread_mutex_t handle2; -}; -#endif // !TQ_RECURSIVE_MUTEX_TYPE - - -// Private class implementation - -// base destructor -TQMutexPrivate::~TQMutexPrivate() -{ - int ret = pthread_mutex_destroy(&handle); - -#ifdef TQT_CHECK_RANGE - if ( ret ) - qWarning( "Mutex destroy failure: %s", strerror( ret ) ); -#endif -} - -// real mutex class -TQRealMutexPrivate::TQRealMutexPrivate(bool recurs) - : recursive(recurs) -{ - pthread_mutexattr_t attr; - pthread_mutexattr_init(&attr); - TQ_MUTEX_SET_TYPE(&attr, recursive ? TQ_RECURSIVE_MUTEX_TYPE : TQ_NORMAL_MUTEX_TYPE); - TQ_UNUSED(recursive); - int ret = pthread_mutex_init(&handle, &attr); - pthread_mutexattr_destroy(&attr); - -#ifdef TQT_CHECK_RANGE - if( ret ) - qWarning( "Mutex init failure: %s", strerror( ret ) ); -#endif // TQT_CHECK_RANGE -} - -void TQRealMutexPrivate::lock() -{ - int ret = pthread_mutex_lock(&handle); - -#ifdef TQT_CHECK_RANGE - if (ret) - qWarning("Mutex lock failure: %s", strerror(ret)); -#endif -} - -void TQRealMutexPrivate::unlock() -{ - int ret = pthread_mutex_unlock(&handle); - -#ifdef TQT_CHECK_RANGE - if (ret) - qWarning("Mutex unlock failure: %s", strerror(ret)); -#endif -} - -bool TQRealMutexPrivate::locked() -{ - int ret = pthread_mutex_trylock(&handle); - - if (ret == EBUSY) { - return TRUE; - } else if (ret) { -#ifdef TQT_CHECK_RANGE - qWarning("Mutex locktest failure: %s", strerror(ret)); -#endif - } else - pthread_mutex_unlock(&handle); - - return FALSE; -} - -bool TQRealMutexPrivate::trylock() -{ - int ret = pthread_mutex_trylock(&handle); - - if (ret == EBUSY) { - return FALSE; - } else if (ret) { -#ifdef TQT_CHECK_RANGE - qWarning("Mutex trylock failure: %s", strerror(ret)); -#endif - return FALSE; - } - - return TRUE; -} - -int TQRealMutexPrivate::type() const -{ - return recursive ? TQ_MUTEX_RECURSIVE : TQ_MUTEX_NORMAL; -} - - -#ifndef TQ_RECURSIVE_MUTEX_TYPE -TQRecursiveMutexPrivate::TQRecursiveMutexPrivate() - : count(0), owner(0) -{ - pthread_mutexattr_t attr; - pthread_mutexattr_init(&attr); - TQ_MUTEX_SET_TYPE(&attr, TQ_NORMAL_MUTEX_TYPE); - int ret = pthread_mutex_init(&handle, &attr); - pthread_mutexattr_destroy(&attr); - -# ifdef TQT_CHECK_RANGE - if (ret) - qWarning( "Mutex init failure: %s", strerror(ret) ); -# endif - - pthread_mutexattr_init(&attr); - ret = pthread_mutex_init( &handle2, &attr ); - pthread_mutexattr_destroy(&attr); - -# ifdef TQT_CHECK_RANGE - if (ret) - qWarning( "Mutex init failure: %s", strerror(ret) ); -# endif -} - -TQRecursiveMutexPrivate::~TQRecursiveMutexPrivate() -{ - int ret = pthread_mutex_destroy(&handle2); - -# ifdef TQT_CHECK_RANGE - if (ret) - qWarning( "Mutex destroy failure: %s", strerror(ret) ); -# endif -} - -void TQRecursiveMutexPrivate::lock() -{ - pthread_mutex_lock(&handle2); - - if (count > 0 && owner == (unsigned long) pthread_self()) { - count++; - } else { - pthread_mutex_unlock(&handle2); - pthread_mutex_lock(&handle); - pthread_mutex_lock(&handle2); - count = 1; - owner = (unsigned long) pthread_self(); - } - - pthread_mutex_unlock(&handle2); -} - -void TQRecursiveMutexPrivate::unlock() -{ - pthread_mutex_lock(&handle2); - - if (owner == (unsigned long) pthread_self()) { - // do nothing if the count is already 0... to reflect the behaviour described - // in the docs - if (count && (--count) < 1) { - count = 0; - pthread_mutex_unlock(&handle); - } - } else { -#ifdef TQT_CHECK_RANGE - qWarning("TQMutex::unlock: unlock from different thread than locker"); - qWarning(" was locked by %d, unlock attempt from %d", - (int)owner, (int)pthread_self()); -#endif - } - - pthread_mutex_unlock(&handle2); -} - -bool TQRecursiveMutexPrivate::locked() -{ - pthread_mutex_lock(&handle2); - - bool ret; - int code = pthread_mutex_trylock(&handle); - - if (code == EBUSY) { - ret = TRUE; - } else { -#ifdef TQT_CHECK_RANGE - if (code) - qWarning("Mutex trylock failure: %s", strerror(code)); -#endif - - pthread_mutex_unlock(&handle); - ret = FALSE; - } - - pthread_mutex_unlock(&handle2); - - return ret; -} - -bool TQRecursiveMutexPrivate::trylock() -{ - bool ret = TRUE; - - pthread_mutex_lock(&handle2); - - if ( count > 0 && owner == (unsigned long) pthread_self() ) { - count++; - } else { - int code = pthread_mutex_trylock(&handle); - - if (code == EBUSY) { - ret = FALSE; - } else if (code) { -#ifdef TQT_CHECK_RANGE - qWarning("Mutex trylock failure: %s", strerror(code)); -#endif - ret = FALSE; - } else { - count = 1; - owner = (unsigned long) pthread_self(); - } - } - - pthread_mutex_unlock(&handle2); - - return ret; -} - -int TQRecursiveMutexPrivate::type() const -{ - return TQ_MUTEX_RECURSIVE; -} - -#endif // !TQ_RECURSIVE_MUTEX_TYPE - - -/*! - \class TQMutex tqmutex.h - \threadsafe - \brief The TQMutex class provides access serialization between threads. - - \ingroup thread - \ingroup environment - - The purpose of a TQMutex is to protect an object, data structure or - section of code so that only one thread can access it at a time - (This is similar to the Java \c synchronized keyword). For - example, say there is a method which prints a message to the user - on two lines: - - \code - int number = 6; - - void method1() - { - number *= 5; - number /= 4; - } - - void method2() - { - number *= 3; - number /= 2; - } - \endcode - - If these two methods are called in succession, the following happens: - - \code - // method1() - number *= 5; // number is now 30 - number /= 4; // number is now 7 - - // method2() - number *= 3; // nubmer is now 21 - number /= 2; // number is now 10 - \endcode - - If these two methods are called simultaneously from two threads then the - following sequence could result: - - \code - // Thread 1 calls method1() - number *= 5; // number is now 30 - - // Thread 2 calls method2(). - // - // Most likely Thread 1 has been put to sleep by the operating - // system to allow Thread 2 to run. - number *= 3; // number is now 90 - number /= 2; // number is now 45 - - // Thread 1 finishes executing. - number /= 4; // number is now 11, instead of 10 - \endcode - - If we add a mutex, we should get the result we want: - - \code - TQMutex mutex; - int number = 6; - - void method1() - { - mutex.lock(); - number *= 5; - number /= 4; - mutex.unlock(); - } - - void method2() - { - mutex.lock(); - number *= 3; - number /= 2; - mutex.unlock(); - } - \endcode - - Then only one thread can modify \c number at any given time and - the result is correct. This is a trivial example, of course, but - applies to any other case where things need to happen in a - particular sequence. - - When you call lock() in a thread, other threads that try to call - lock() in the same place will block until the thread that got the - lock calls unlock(). A non-blocking alternative to lock() is - tryLock(). -*/ - -/*! - Constructs a new mutex. The mutex is created in an unlocked state. - A recursive mutex is created if \a recursive is TRUE; a normal - mutex is created if \a recursive is FALSE (the default). With a - recursive mutex, a thread can lock the same mutex multiple times - and it will not be unlocked until a corresponding number of - unlock() calls have been made. -*/ -TQMutex::TQMutex(bool recursive) -{ -#ifndef TQ_RECURSIVE_MUTEX_TYPE - if ( recursive ) - d = new TQRecursiveMutexPrivate(); - else -#endif // !TQ_RECURSIVE_MUTEX_TYPE - d = new TQRealMutexPrivate(recursive); -} - -/*! - Destroys the mutex. - - \warning If you destroy a mutex that still holds a lock the - resultant behavior is undefined. -*/ -TQMutex::~TQMutex() -{ - delete d; -} - -/*! - Attempt to lock the mutex. If another thread has locked the mutex - then this call will \e block until that thread has unlocked it. - - \sa unlock(), locked() -*/ -void TQMutex::lock() -{ - d->lock(); -} - -/*! - Unlocks the mutex. Attempting to unlock a mutex in a different - thread to the one that locked it results in an error. Unlocking a - mutex that is not locked results in undefined behaviour (varies - between different Operating Systems' thread implementations). - - \sa lock(), locked() -*/ -void TQMutex::unlock() -{ - d->unlock(); -} - -/*! - Returns TRUE if the mutex is locked by another thread; otherwise - returns FALSE. - - \warning Due to differing implementations of recursive mutexes on - various platforms, calling this function from the same thread that - previously locked the mutex will return undefined results. - - \sa lock(), unlock() -*/ -bool TQMutex::locked() -{ - return d->locked(); -} - -/*! - Attempt to lock the mutex. If the lock was obtained, this function - returns TRUE. If another thread has locked the mutex, this - function returns FALSE, instead of waiting for the mutex to become - available, i.e. it does not block. - - If the lock was obtained, the mutex must be unlocked with unlock() - before another thread can successfully lock it. - - \sa lock(), unlock(), locked() -*/ -bool TQMutex::tryLock() -{ - return d->trylock(); -} - -/*! - \class TQMutexLocker tqmutex.h - \brief The TQMutexLocker class simplifies locking and unlocking TQMutexes. - - \threadsafe - - \ingroup thread - \ingroup environment - - The purpose of TQMutexLocker is to simplify TQMutex locking and - unlocking. Locking and unlocking a TQMutex in complex functions and - statements or in exception handling code is error prone and - difficult to debug. TQMutexLocker should be used in such situations - to ensure that the state of the mutex is well defined and always - locked and unlocked properly. - - TQMutexLocker should be created within a function where a TQMutex - needs to be locked. The mutex is locked when TQMutexLocker is - created, and unlocked when TQMutexLocker is destroyed. - - For example, this complex function locks a TQMutex upon entering - the function and unlocks the mutex at all the exit points: - - \code - int complexFunction( int flag ) - { - mutex.lock(); - - int return_value = 0; - - switch ( flag ) { - case 0: - case 1: - { - mutex.unlock(); - return moreComplexFunction( flag ); - } - - case 2: - { - int status = anotherFunction(); - if ( status < 0 ) { - mutex.unlock(); - return -2; - } - return_value = status + flag; - break; - } - - default: - { - if ( flag > 10 ) { - mutex.unlock(); - return -1; - } - break; - } - } - - mutex.unlock(); - return return_value; - } - \endcode - - This example function will get more complicated as it is - developed, which increases the likelihood that errors will occur. - - Using TQMutexLocker greatly simplifies the code, and makes it more - readable: - - \code - int complexFunction( int flag ) - { - TQMutexLocker locker( &mutex ); - - int return_value = 0; - - switch ( flag ) { - case 0: - case 1: - { - return moreComplexFunction( flag ); - } - - case 2: - { - int status = anotherFunction(); - if ( status < 0 ) - return -2; - return_value = status + flag; - break; - } - - default: - { - if ( flag > 10 ) - return -1; - break; - } - } - - return return_value; - } - \endcode - - Now, the mutex will always be unlocked when the TQMutexLocker - object is destroyed (when the function returns since \c locker is - an auto variable). Note that the mutex will be unlocked after - the call to moreComplexFunction() in this example, avoiding - possible bugs caused by unlocking the mutex too early, as in - the first example. - - The same principle applies to code that throws and catches - exceptions. An exception that is not caught in the function that - has locked the mutex has no way of unlocking the mutex before the - exception is passed up the stack to the calling function. - - TQMutexLocker also provides a mutex() member function that returns - the mutex on which the TQMutexLocker is operating. This is useful - for code that needs access to the mutex, such as - TQWaitCondition::wait(). For example: - - \code - class SignalWaiter - { - private: - TQMutexLocker locker; - - public: - SignalWaiter( TQMutex *mutex ) - : locker( mutex ) - { - } - - void waitForSignal() - { - ... - ... - ... - - while ( ! signalled ) - waitcondition.wait( locker.mutex() ); - - ... - ... - ... - } - }; - \endcode - - \sa TQMutex, TQWaitCondition -*/ - -/*! - \fn TQMutexLocker::TQMutexLocker( TQMutex *mutex ) - - Constructs a TQMutexLocker and locks \a mutex. The mutex will be - unlocked when the TQMutexLocker is destroyed. If \a mutex is zero, - TQMutexLocker does nothing. - - \sa TQMutex::lock() -*/ - -/*! - \fn TQMutexLocker::~TQMutexLocker() - - Destroys the TQMutexLocker and unlocks the mutex which was locked - in the constructor. - - \sa TQMutexLocker::TQMutexLocker(), TQMutex::unlock() -*/ - -/*! - \fn TQMutex *TQMutexLocker::mutex() const - - Returns a pointer to the mutex which was locked in the - constructor. - - \sa TQMutexLocker::TQMutexLocker() -*/ - -#endif // TQT_THREAD_SUPPORT |