From aeefd3fe454bfaed093355278b1e2caa84bfd77a Mon Sep 17 00:00:00 2001 From: Michele Calgaro Date: Sun, 30 Jun 2024 12:33:25 +0900 Subject: Rename threading nt* related files to equivalent tq* Signed-off-by: Michele Calgaro --- src/tools/ntqmutex.h | 117 -------- src/tools/ntqsemaphore.h | 81 ------ src/tools/ntqthreadstorage.h | 95 ------- src/tools/ntqwaitcondition.h | 79 ------ src/tools/qcomlibrary.cpp | 2 +- src/tools/qcstring.cpp | 2 +- src/tools/qdir_unix.cpp | 2 +- src/tools/qgarray.cpp | 2 +- src/tools/qglist.cpp | 2 +- src/tools/qgvector.cpp | 2 +- src/tools/qlocale.cpp | 4 +- src/tools/qmutex_p.h | 74 ----- src/tools/qmutex_unix.cpp | 535 ------------------------------------- src/tools/qmutexpool.cpp | 155 ----------- src/tools/qmutexpool_p.h | 80 ------ src/tools/qregexp.cpp | 4 +- src/tools/qsemaphore.cpp | 255 ------------------ src/tools/qt_tools.pri | 30 +-- src/tools/qthreadinstance_p.h | 111 -------- src/tools/qthreadstorage_unix.cpp | 366 ------------------------- src/tools/qwaitcondition_unix.cpp | 316 ---------------------- src/tools/tqmutex.h | 117 ++++++++ src/tools/tqmutex_p.h | 74 +++++ src/tools/tqmutex_unix.cpp | 535 +++++++++++++++++++++++++++++++++++++ src/tools/tqmutexpool.cpp | 155 +++++++++++ src/tools/tqmutexpool_p.h | 80 ++++++ src/tools/tqsemaphore.cpp | 255 ++++++++++++++++++ src/tools/tqsemaphore.h | 81 ++++++ src/tools/tqstring.cpp | 2 +- src/tools/tqthreadinstance_p.h | 111 ++++++++ src/tools/tqthreadstorage.h | 95 +++++++ src/tools/tqthreadstorage_unix.cpp | 366 +++++++++++++++++++++++++ src/tools/tqwaitcondition.h | 79 ++++++ src/tools/tqwaitcondition_unix.cpp | 316 ++++++++++++++++++++++ 34 files changed, 2290 insertions(+), 2290 deletions(-) delete mode 100644 src/tools/ntqmutex.h delete mode 100644 src/tools/ntqsemaphore.h delete mode 100644 src/tools/ntqthreadstorage.h delete mode 100644 src/tools/ntqwaitcondition.h delete mode 100644 src/tools/qmutex_p.h delete mode 100644 src/tools/qmutex_unix.cpp delete mode 100644 src/tools/qmutexpool.cpp delete mode 100644 src/tools/qmutexpool_p.h delete mode 100644 src/tools/qsemaphore.cpp delete mode 100644 src/tools/qthreadinstance_p.h delete mode 100644 src/tools/qthreadstorage_unix.cpp delete mode 100644 src/tools/qwaitcondition_unix.cpp create mode 100644 src/tools/tqmutex.h create mode 100644 src/tools/tqmutex_p.h create mode 100644 src/tools/tqmutex_unix.cpp create mode 100644 src/tools/tqmutexpool.cpp create mode 100644 src/tools/tqmutexpool_p.h create mode 100644 src/tools/tqsemaphore.cpp create mode 100644 src/tools/tqsemaphore.h create mode 100644 src/tools/tqthreadinstance_p.h create mode 100644 src/tools/tqthreadstorage.h create mode 100644 src/tools/tqthreadstorage_unix.cpp create mode 100644 src/tools/tqwaitcondition.h create mode 100644 src/tools/tqwaitcondition_unix.cpp (limited to 'src/tools') diff --git a/src/tools/ntqmutex.h b/src/tools/ntqmutex.h deleted file mode 100644 index c517c6355..000000000 --- a/src/tools/ntqmutex.h +++ /dev/null @@ -1,117 +0,0 @@ -/**************************************************************************** -** -** Definition of TQMutex class -** -** Created : 931107 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** 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. -** -**********************************************************************/ - -#ifndef TQMUTEX_H -#define TQMUTEX_H - -#ifndef QT_H -#include "ntqglobal.h" -#endif // QT_H - -#if defined(TQT_THREAD_SUPPORT) - -class TQMutexPrivate; - -const int Q_MUTEX_NORMAL = 0; -const int Q_MUTEX_RECURSIVE = 1; - -class TQ_EXPORT TQMutex -{ - friend class TQThread; - friend class TQWaitCondition; - friend class TQWaitConditionPrivate; - -public: - TQMutex(bool recursive = FALSE); - virtual ~TQMutex(); - - void lock(); - void unlock(); - bool locked(); - bool tryLock(); - -private: - TQMutexPrivate * d; - -#if defined(TQ_DISABLE_COPY) - TQMutex( const TQMutex & ); - TQMutex &operator=( const TQMutex & ); -#endif - -public: - int level(); -}; - -class TQ_EXPORT TQMutexLocker -{ -public: - TQMutexLocker( TQMutex * ); - ~TQMutexLocker(); - - TQMutex *mutex() const; - -private: - TQMutex *mtx; - -#if defined(TQ_DISABLE_COPY) - TQMutexLocker( const TQMutexLocker & ); - TQMutexLocker &operator=( const TQMutexLocker & ); -#endif -}; - -inline TQMutexLocker::TQMutexLocker( TQMutex *m ) - : mtx( m ) -{ - if ( mtx ) mtx->lock(); -} - -inline TQMutexLocker::~TQMutexLocker() -{ - if ( mtx ) mtx->unlock(); -} - -inline TQMutex *TQMutexLocker::mutex() const -{ - return mtx; -} - -#endif - -#endif diff --git a/src/tools/ntqsemaphore.h b/src/tools/ntqsemaphore.h deleted file mode 100644 index 0dc8e81de..000000000 --- a/src/tools/ntqsemaphore.h +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** -** -** Definition of TQSemaphore class -** -** Created : 931107 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** 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. -** -**********************************************************************/ - -#ifndef TQSEMAPHORE_H -#define TQSEMAPHORE_H - -#ifndef QT_H -#include "ntqglobal.h" -#endif // QT_H - -#if defined(TQT_THREAD_SUPPORT) - -class TQSemaphorePrivate; - -class TQ_EXPORT TQSemaphore -{ -public: - TQSemaphore( int ); - virtual ~TQSemaphore(); - - int available() const; - int total() const; - - // postfix operators - int operator++(int); - int operator--(int); - - int operator+=(int); - int operator-=(int); - - bool tryAccess(int); - -private: - TQSemaphorePrivate *d; - -#if defined(TQ_DISABLE_COPY) - TQSemaphore(const TQSemaphore &); - TQSemaphore &operator=(const TQSemaphore &); -#endif -}; - -#endif - -#endif diff --git a/src/tools/ntqthreadstorage.h b/src/tools/ntqthreadstorage.h deleted file mode 100644 index 588621237..000000000 --- a/src/tools/ntqthreadstorage.h +++ /dev/null @@ -1,95 +0,0 @@ -/**************************************************************************** -** -** ... -** -** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. -** -** 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. -** -**********************************************************************/ - -#ifndef TQTHREADSTORAGE_H -#define TQTHREADSTORAGE_H - -#ifdef TQT_THREAD_SUPPORT - -#ifndef QT_H -#include "ntqglobal.h" -#endif // QT_H - -class TQ_EXPORT TQThreadStorageData -{ -public: - TQThreadStorageData( void (*func)(void *) ); - ~TQThreadStorageData(); - - void** get() const; - void** set( void* p ); - - static void finish( void** ); - int id; -}; - - -template -class TQThreadStorage -{ -private: - TQThreadStorageData d; - -#if defined(TQ_DISABLE_COPY) - // disable copy constructor and operator= - TQThreadStorage( const TQThreadStorage & ); - TQThreadStorage &operator=( const TQThreadStorage & ); -#endif // TQ_DISABLE_COPY - - static void deleteData( void *x ) { delete (T)x; } - -public: - inline TQThreadStorage() : d( deleteData ) { } - inline ~TQThreadStorage() { } - - inline bool hasLocalData() const - { return d.get() != 0; } - - inline T& localData() - { void **v = d.get(); if ( !v ) v = d.set( 0 ); return *(T*)v; } - - inline T localData() const - { void **v = d.get(); return ( v ? *(T*)v : 0 ); } - - inline void setLocalData( T t ) - { (void) d.set( t ); } -}; - -#endif // TQT_THREAD_SUPPORT - -#endif // TQTHREADSTORAGE_H diff --git a/src/tools/ntqwaitcondition.h b/src/tools/ntqwaitcondition.h deleted file mode 100644 index 503d5d6c9..000000000 --- a/src/tools/ntqwaitcondition.h +++ /dev/null @@ -1,79 +0,0 @@ -/**************************************************************************** -** -** Definition of TQWaitCondition class -** -** Created : 931107 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** 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. -** -**********************************************************************/ - -#ifndef TQWAITCONDITION_H -#define TQWAITCONDITION_H - -#ifndef QT_H -#include "ntqglobal.h" -#endif // QT_H - -#if defined(TQT_THREAD_SUPPORT) - -#include - -class TQWaitConditionPrivate; -class TQMutex; - -class TQ_EXPORT TQWaitCondition -{ -public: - TQWaitCondition(); - virtual ~TQWaitCondition(); - - // default argument causes thread to block indefinately - bool wait( unsigned long time = ULONG_MAX ); - bool wait( TQMutex *mutex, unsigned long time = ULONG_MAX ); - - void wakeOne(); - void wakeAll(); - -private: - TQWaitConditionPrivate * d; - -#if defined(TQ_DISABLE_COPY) - TQWaitCondition( const TQWaitCondition & ); - TQWaitCondition &operator=( const TQWaitCondition & ); -#endif -}; - -#endif - -#endif diff --git a/src/tools/qcomlibrary.cpp b/src/tools/qcomlibrary.cpp index 27ffbb8ce..cc7647da9 100644 --- a/src/tools/qcomlibrary.cpp +++ b/src/tools/qcomlibrary.cpp @@ -49,7 +49,7 @@ #endif // NO_ERROR_H #ifdef TQT_THREAD_SUPPORT -# include "qmutexpool_p.h" +# include "tqmutexpool_p.h" #endif // TQT_THREAD_SUPPORT #ifndef QT_DEBUG_COMPONENT diff --git a/src/tools/qcstring.cpp b/src/tools/qcstring.cpp index 80381e8b9..d35b06e3e 100644 --- a/src/tools/qcstring.cpp +++ b/src/tools/qcstring.cpp @@ -44,7 +44,7 @@ #include "ntqdatastream.h" #ifdef TQT_THREAD_SUPPORT -# include +# include #endif // TQT_THREAD_SUPPORT #include diff --git a/src/tools/qdir_unix.cpp b/src/tools/qdir_unix.cpp index 19e03e642..8019d7b16 100644 --- a/src/tools/qdir_unix.cpp +++ b/src/tools/qdir_unix.cpp @@ -49,7 +49,7 @@ #include "tqstringlist.h" #ifdef TQT_THREAD_SUPPORT -# include +# include #endif // TQT_THREAD_SUPPORT #include diff --git a/src/tools/qgarray.cpp b/src/tools/qgarray.cpp index ff1f7b08b..1470d100e 100644 --- a/src/tools/qgarray.cpp +++ b/src/tools/qgarray.cpp @@ -53,7 +53,7 @@ #include #ifdef TQT_THREAD_SUPPORT -# include +# include #endif // TQT_THREAD_SUPPORT /* diff --git a/src/tools/qglist.cpp b/src/tools/qglist.cpp index 1afa67b41..95e66b38f 100644 --- a/src/tools/qglist.cpp +++ b/src/tools/qglist.cpp @@ -44,7 +44,7 @@ #include "tqvaluelist.h" #if defined(TQT_THREAD_SUPPORT) - #include "ntqmutex.h" + #include "tqmutex.h" #endif // defined(TQT_THREAD_SUPPORT) /*! diff --git a/src/tools/qgvector.cpp b/src/tools/qgvector.cpp index 81b7a2006..1c6c8669e 100644 --- a/src/tools/qgvector.cpp +++ b/src/tools/qgvector.cpp @@ -52,7 +52,7 @@ #include #ifdef TQT_THREAD_SUPPORT -# include +# include #endif // TQT_THREAD_SUPPORT #define USE_MALLOC // comment to use new/delete diff --git a/src/tools/qlocale.cpp b/src/tools/qlocale.cpp index d7716a1a7..fc02f8ef2 100644 --- a/src/tools/qlocale.cpp +++ b/src/tools/qlocale.cpp @@ -48,8 +48,8 @@ #include "ntqnamespace.h" #ifdef QT_QLOCALE_USES_FCVT -# include -# include +# include +# include #endif #if defined (Q_OS_WIN) diff --git a/src/tools/qmutex_p.h b/src/tools/qmutex_p.h deleted file mode 100644 index 3e9de8e5c..000000000 --- a/src/tools/qmutex_p.h +++ /dev/null @@ -1,74 +0,0 @@ -/**************************************************************************** -** -** TQMutex private class declarations -** -** Created : 20012507 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** 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. -** -**********************************************************************/ - -#ifndef TQMUTEX_P_H -#define TQMUTEX_P_H - -#ifndef QT_H -#endif // QT_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the TQt API. It exists for the convenience -// of qmutex_unix.cpp and qmutex_win.cpp. This header file may change -// from version to version without notice, or even be removed. -// -// We mean it. -// - -class TQMutexPrivate { -public: - // Q_MUTEX_T is defined in the various *.cpp files - Q_MUTEX_T handle; - - virtual ~TQMutexPrivate(); - - virtual void lock() = 0; - virtual void unlock() = 0; - virtual bool locked() = 0; - virtual bool trylock() = 0; - virtual int type() const = 0; - virtual int level() = 0; -}; - - -#endif // TQMUTEX_P_H diff --git a/src/tools/qmutex_unix.cpp b/src/tools/qmutex_unix.cpp deleted file mode 100644 index 597d3e628..000000000 --- a/src/tools/qmutex_unix.cpp +++ /dev/null @@ -1,535 +0,0 @@ -/**************************************************************************** -** -** TQMutex class for Unix -** -** Created : 20010725 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** 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 "qplatformdefs.h" - -typedef pthread_mutex_t Q_MUTEX_T; - -#if defined(QT_CHECK_RANGE) -# define Q_NORMAL_MUTEX_TYPE PTHREAD_MUTEX_ERRORCHECK -#else -# define Q_NORMAL_MUTEX_TYPE PTHREAD_MUTEX_DEFAULT -#endif -#define Q_RECURSIVE_MUTEX_TYPE PTHREAD_MUTEX_RECURSIVE - -#include "ntqmutex.h" -#include "qmutex_p.h" - -#include -#include - -// Private class declarations - -class TQRealMutexPrivate : public TQMutexPrivate { -public: - TQRealMutexPrivate(bool = FALSE); - - void lock(); - void unlock(); - bool locked(); - bool trylock(); - int type() const; - int level(); - - bool recursive; - int count; -}; - - -// Private class implementation - -// base destructor -TQMutexPrivate::~TQMutexPrivate() -{ - int ret = pthread_mutex_destroy(&handle); - -#ifdef QT_CHECK_RANGE - if ( ret ) - tqWarning( "Mutex destroy failure: %s", strerror( ret ) ); -#endif -} - -// real mutex class -TQRealMutexPrivate::TQRealMutexPrivate(bool recurs) - : recursive(recurs), count(0) -{ - pthread_mutexattr_t attr; - pthread_mutexattr_init(&attr); - pthread_mutexattr_settype(&attr, recursive ? Q_RECURSIVE_MUTEX_TYPE : Q_NORMAL_MUTEX_TYPE); - int ret = pthread_mutex_init(&handle, &attr); - pthread_mutexattr_destroy(&attr); - -#ifdef QT_CHECK_RANGE - if( ret ) - tqWarning( "Mutex init failure: %s", strerror( ret ) ); -#endif // QT_CHECK_RANGE -} - -void TQRealMutexPrivate::lock() -{ - int ret = pthread_mutex_lock(&handle); - - if (!ret) { - count++; - } else { -#ifdef QT_CHECK_RANGE - tqWarning("Mutex lock failure: %s", strerror(ret)); -#endif - } -} - -void TQRealMutexPrivate::unlock() -{ - count--; - int ret = pthread_mutex_unlock(&handle); - - if (ret) { - count++; -#ifdef QT_CHECK_RANGE - tqWarning("Mutex unlock failure: %s", strerror(ret)); -#endif - } -} - -bool TQRealMutexPrivate::locked() -{ - return count > 0; -} - -bool TQRealMutexPrivate::trylock() -{ - int ret = pthread_mutex_trylock(&handle); - - if (ret == EBUSY) { - return FALSE; - } else if (ret) { -#ifdef QT_CHECK_RANGE - tqWarning("Mutex trylock failure: %s", strerror(ret)); -#endif - return FALSE; - } - - return TRUE; -} - -int TQRealMutexPrivate::type() const -{ - return recursive ? Q_MUTEX_RECURSIVE : Q_MUTEX_NORMAL; -} - -int TQRealMutexPrivate::level() -{ - return count; -} - - -/*! - \class TQMutex ntqmutex.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) -{ - 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(); -} - -/*! - Returns the current lock level of the mutex. - 0 means the mutex is unlocked - This method should only be called when the mutex has already been locked - by lock(), otherwise the lock level could change before the next line - of code is executed. - - WARNING: Non-recursive mutexes will never exceed a lock level of 1! - - \sa lock(), unlock(), locked() -*/ -int TQMutex::level() -{ - return d->level(); -} - -/*! - \class TQMutexLocker ntqmutex.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 diff --git a/src/tools/qmutexpool.cpp b/src/tools/qmutexpool.cpp deleted file mode 100644 index 72c66c8ca..000000000 --- a/src/tools/qmutexpool.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/**************************************************************************** -** -** ... -** -** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. -** -** 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. -** -**********************************************************************/ - -#include "qmutexpool_p.h" - -#ifdef TQT_THREAD_SUPPORT - -#include - -TQ_EXPORT TQMutexPool *tqt_global_mutexpool = 0; - - -/*! - \class TQMutexPool qmutexpool_p.h - \brief The TQMutexPool class provides a pool of TQMutex objects. - - \internal - - \ingroup thread - - TQMutexPool is a convenience class that provides access to a fixed - number of TQMutex objects. - - Typical use of a TQMutexPool is in situations where it is not - possible or feasible to use one TQMutex for every protected object. - The mutex pool will return a mutex based on the address of the - object that needs protection. - - For example, consider this simple class: - - \code - class Number { - public: - Number( double n ) : num ( n ) { } - - void setNumber( double n ) { num = n; } - double number() const { return num; } - - private: - double num; - }; - \endcode - - Adding a TQMutex member to the Number class does not make sense, - because it is so small. However, in order to ensure that access to - each Number is protected, you need to use a mutex. In this case, a - TQMutexPool would be ideal. - - Code to calculate the square of a number would then look something - like this: - - \code - void calcSquare( Number *num ) - { - TQMutexLocker locker( mutexpool.get( num ) ); - num.setNumber( num.number() * num.number() ); - } - \endcode - - This function will safely calculate the square of a number, since - it uses a mutex from a TQMutexPool. The mutex is locked and - unlocked automatically by the TQMutexLocker class. See the - TQMutexLocker documentation for more details. -*/ - -/*! - Constructs a TQMutexPool, reserving space for \a size TQMutexes. If - \a recursive is TRUE, all TQMutexes in the pool will be recursive - mutexes; otherwise they will all be non-recursive (the default). - - The TQMutexes are created when needed, and deleted when the - TQMutexPool is destructed. -*/ -TQMutexPool::TQMutexPool( bool recursive, int size ) - : mutex( FALSE ), count( size ), recurs( recursive ) -{ - mutexes = new TQMutex*[count]; - for ( int index = 0; index < count; ++index ) { - mutexes[index] = 0; - } -} - -/*! - Destructs a TQMutexPool. All TQMutexes that were created by the pool - are deleted. -*/ -TQMutexPool::~TQMutexPool() -{ - TQMutexLocker locker( &mutex ); - for ( int index = 0; index < count; ++index ) { - delete mutexes[index]; - mutexes[index] = 0; - } - delete [] mutexes; - mutexes = 0; -} - -/*! - Returns a TQMutex from the pool. TQMutexPool uses the value \a - address to determine which mutex is retured from the pool. -*/ -TQMutex *TQMutexPool::get( void *address ) -{ - int index = (int) ( (unsigned long) address % count ); - - if ( ! mutexes[index] ) { - // mutex not created, create one - - TQMutexLocker locker( &mutex ); - // we need to check once again that the mutex hasn't been created, since - // 2 threads could be trying to create a mutex as the same index... - if ( ! mutexes[index] ) { - mutexes[index] = new TQMutex( recurs ); - } - } - - return mutexes[index]; -} - -#endif diff --git a/src/tools/qmutexpool_p.h b/src/tools/qmutexpool_p.h deleted file mode 100644 index a0bb28562..000000000 --- a/src/tools/qmutexpool_p.h +++ /dev/null @@ -1,80 +0,0 @@ -/**************************************************************************** -** -** ... -** -** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. -** -** 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. -** -**********************************************************************/ - -#ifndef TQMUTEXPOOL_P_H -#define TQMUTEXPOOL_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the TQt API. It exists for the convenience -// of TQSettings. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// -// - -#ifdef TQT_THREAD_SUPPORT - -#ifndef QT_H -#include "ntqmutex.h" -#include "ntqmemarray.h" -#endif // QT_H - -class TQ_EXPORT TQMutexPool -{ -public: - TQMutexPool( bool recursive = FALSE, int size = 17 ); - ~TQMutexPool(); - - TQMutex *get( void *address ); - -private: - TQMutex mutex; - TQMutex **mutexes; - int count; - bool recurs; -}; - -extern TQ_EXPORT TQMutexPool *tqt_global_mutexpool; - -#endif // TQT_THREAD_SUPPORT - -#endif // TQMUTEXPOOL_P_H diff --git a/src/tools/qregexp.cpp b/src/tools/qregexp.cpp index 612e31194..e6447cdf1 100644 --- a/src/tools/qregexp.cpp +++ b/src/tools/qregexp.cpp @@ -53,8 +53,8 @@ #include "ntqtl.h" #ifdef TQT_THREAD_SUPPORT -#include "ntqthreadstorage.h" -#include +#include "tqthreadstorage.h" +#include #endif // TQT_THREAD_SUPPORT #undef TQT_TRANSLATE_NOOP diff --git a/src/tools/qsemaphore.cpp b/src/tools/qsemaphore.cpp deleted file mode 100644 index 810837b4c..000000000 --- a/src/tools/qsemaphore.cpp +++ /dev/null @@ -1,255 +0,0 @@ -/**************************************************************************** -** -** TQSemaphore class for Unix -** -** Created : 20010725 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** 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 "ntqsemaphore.h" -#include "ntqmutex.h" -#include "ntqwaitcondition.h" - - -/*! - \class TQSemaphore ntqsemaphore.h - \threadsafe - \brief The TQSemaphore class provides a robust integer semaphore. - - \ingroup thread - \ingroup environment - - A TQSemaphore can be used to serialize thread execution, in a - similar way to a TQMutex. A semaphore differs from a mutex, in - that a semaphore can be accessed by more than one thread at a - time. - - For example, suppose we have an application that stores data in a - large tree structure. The application creates 10 threads - (commonly called a thread pool) to perform searches on the tree. - When the application searches the tree for some piece of data, it - uses one thread per base node to do the searching. A semaphore - could be used to make sure that two threads don't try to search - the same branch of the tree at the same time. - - A non-computing example of a semaphore would be dining at a - restuarant. A semaphore is initialized to have a maximum count - equal to the number of chairs in the restuarant. As people - arrive, they want a seat. As seats are filled, the semaphore is - accessed, once per person. As people leave, the access is - released, allowing more people to enter. If a party of 10 people - want to be seated, but there are only 9 seats, those 10 people - will wait, but a party of 4 people would be seated (taking the - available seats to 5, making the party of 10 people wait longer). - - When a semaphore is created it is given a number which is the - maximum number of concurrent accesses it will permit. Accesses to - the sempahore are gained using operator++() or operator+=(), and - released with operator--() or operator-=(). The number of - accesses allowed is retrieved with available(), and the total - number with total(). Note that the incrementing functions will - block if there aren't enough available accesses. Use tryAccess() - if you want to acquire accesses without blocking. -*/ - - -class TQSemaphorePrivate { -public: - TQSemaphorePrivate(int); - - TQMutex mutex; - TQWaitCondition cond; - - int value, max; -}; - - -TQSemaphorePrivate::TQSemaphorePrivate(int m) - : mutex(FALSE), value(0), max(m) -{ -} - - -/*! - Creates a new semaphore. The semaphore can be concurrently - accessed at most \a maxcount times. -*/ -TQSemaphore::TQSemaphore(int maxcount) -{ - d = new TQSemaphorePrivate(maxcount); -} - - -/*! - Destroys the semaphore. - - \warning If you destroy a semaphore that has accesses in use the - resultant behavior is undefined. -*/ -TQSemaphore::~TQSemaphore() -{ - delete d; -} - - -/*! - Postfix ++ operator. - - Try to get access to the semaphore. If \l available() == 0, this - call will block until it can get access, i.e. until available() \> - 0. -*/ -int TQSemaphore::operator++(int) -{ - TQMutexLocker locker(&d->mutex); - while (d->value >= d->max) - d->cond.wait(locker.mutex()); - - ++d->value; - if (d->value > d->max) - d->value = d->max; - - return d->value; -} - - -/*! - Postfix -- operator. - - Release access of the semaphore. This wakes all threads waiting - for access to the semaphore. -*/ -int TQSemaphore::operator--(int) -{ - TQMutexLocker locker(&d->mutex); - - --d->value; - if (d->value < 0) - d->value = 0; - - d->cond.wakeAll(); - - return d->value; -} - - -/*! - Try to get access to the semaphore. If \l available() \< \a n, this - call will block until it can get all the accesses it wants, i.e. - until available() \>= \a n. -*/ -int TQSemaphore::operator+=(int n) -{ - TQMutexLocker locker(&d->mutex); - - if ( n < 0 || n > d->max ) { -#ifdef QT_CHECK_RANGE - tqWarning( "TQSemaphore::operator+=: paramter %d out of range", n ); -#endif // QT_CHECK_RANGE - n = n < 0 ? 0 : d->max; - } - - while (d->value + n > d->max) - d->cond.wait(locker.mutex()); - - d->value += n; - - return d->value; -} - - -/*! - Release \a n accesses to the semaphore. -*/ -int TQSemaphore::operator-=(int n) -{ - TQMutexLocker locker(&d->mutex); - - if ( n < 0 || n > d->value ) { -#ifdef QT_CHECK_RANGE - tqWarning( "TQSemaphore::operator-=: paramter %d out of range", n ); -#endif // QT_CHECK_RANGE - n = n < 0 ? 0 : d->value; - } - - d->value -= n; - d->cond.wakeAll(); - - return d->value; -} - - -/*! - Returns the number of accesses currently available to the - semaphore. -*/ -int TQSemaphore::available() const -{ - TQMutexLocker locker(&d->mutex); - return d->max - d->value; -} - - -/*! - Returns the total number of accesses to the semaphore. -*/ -int TQSemaphore::total() const -{ - TQMutexLocker locker(&d->mutex); - return d->max; -} - - -/*! - Try to get access to the semaphore. If \l available() \< \a n, this - function will return FALSE immediately. If \l available() \>= \a n, - this function will take \a n accesses and return TRUE. This - function does \e not block. -*/ -bool TQSemaphore::tryAccess(int n) -{ - TQMutexLocker locker(&d->mutex); - - if (d->value + n > d->max) - return FALSE; - - d->value += n; - - return TRUE; -} - -#endif // TQT_THREAD_SUPPORT diff --git a/src/tools/qt_tools.pri b/src/tools/qt_tools.pri index b57e00435..d52bbd339 100644 --- a/src/tools/qt_tools.pri +++ b/src/tools/qt_tools.pri @@ -38,15 +38,15 @@ tools { $$TOOLS_P/qlocale_p.h \ $$TOOLS_H/tqptrlist.h \ $$TOOLS_H/tqmap.h \ - $$TOOLS_H/ntqmutex.h \ - $$TOOLS_P/qmutex_p.h \ - $$TOOLS_P/qmutexpool_p.h \ + $$TOOLS_H/tqmutex.h \ + $$TOOLS_P/tqmutex_p.h \ + $$TOOLS_P/tqmutexpool_p.h \ $$TOOLS_P/qpluginmanager_p.h \ $$TOOLS_H/tqptrcollection.h \ $$TOOLS_H/tqptrdict.h \ $$TOOLS_H/tqptrqueue.h \ $$TOOLS_H/ntqregexp.h \ - $$TOOLS_H/ntqsemaphore.h \ + $$TOOLS_H/tqsemaphore.h \ $$TOOLS_H/ntqsettings.h \ $$TOOLS_P/qsettings_p.h \ $$TOOLS_H/ntqshared.h \ @@ -56,14 +56,14 @@ tools { $$TOOLS_H/tqstrlist.h \ $$TOOLS_H/tqstrvec.h \ $$TOOLS_H/tqtextstream.h \ - $$TOOLS_P/qthreadinstance_p.h \ - $$TOOLS_H/ntqthreadstorage.h\ + $$TOOLS_P/tqthreadinstance_p.h \ + $$TOOLS_H/tqthreadstorage.h\ $$TOOLS_P/qunicodetables_p.h \ $$TOOLS_H/tqptrvector.h \ $$TOOLS_H/tqvaluelist.h \ $$TOOLS_H/tqvaluestack.h \ $$TOOLS_H/tqvaluevector.h \ - $$TOOLS_H/ntqwaitcondition.h \ + $$TOOLS_H/tqwaitcondition.h \ $$TOOLS_P/qcom_p.h \ $$TOOLS_P/qucom_p.h \ $$TOOLS_H/ntquuid.h @@ -73,9 +73,9 @@ tools { $$TOOLS_CPP/qfileinfo_win.cpp \ $$TOOLS_CPP/qlibrary_win.cpp \ $$TOOLS_CPP/qsettings_win.cpp \ - $$TOOLS_CPP/qmutex_win.cpp \ - $$TOOLS_CPP/qwaitcondition_win.cpp \ - $$TOOLS_CPP/qthreadstorage_win.cpp \ + $$TOOLS_CPP/tqmutex_win.cpp \ + $$TOOLS_CPP/tqwaitcondition_win.cpp \ + $$TOOLS_CPP/tqthreadstorage_win.cpp \ $$TOOLS_CPP/qcriticalsection_p.cpp win32-borland:SOURCES += $$TOOLS_CPP/qwinexport.cpp @@ -95,9 +95,9 @@ tools { else:unix:SOURCES += $$TOOLS_CPP/qdir_unix.cpp \ $$TOOLS_CPP/qfile_unix.cpp \ $$TOOLS_CPP/qfileinfo_unix.cpp \ - $$TOOLS_CPP/qmutex_unix.cpp \ - $$TOOLS_CPP/qthreadstorage_unix.cpp \ - $$TOOLS_CPP/qwaitcondition_unix.cpp + $$TOOLS_CPP/tqmutex_unix.cpp \ + $$TOOLS_CPP/tqthreadstorage_unix.cpp \ + $$TOOLS_CPP/tqwaitcondition_unix.cpp mac:!x11:!embedded:SOURCES += $$TOOLS_CPP/qsettings_mac.cpp mac { @@ -128,11 +128,11 @@ tools { $$TOOLS_CPP/qlibrary.cpp \ $$TOOLS_CPP/qlocale.cpp \ $$TOOLS_CPP/tqmap.cpp \ - $$TOOLS_CPP/qmutexpool.cpp \ + $$TOOLS_CPP/tqmutexpool.cpp \ $$TOOLS_CPP/tqptrcollection.cpp \ $$TOOLS_CPP/qregexp.cpp \ $$TOOLS_CPP/tqstring.cpp \ - $$TOOLS_CPP/qsemaphore.cpp \ + $$TOOLS_CPP/tqsemaphore.cpp \ $$TOOLS_CPP/qsettings.cpp \ $$TOOLS_CPP/tqstringlist.cpp \ $$TOOLS_CPP/tqtextstream.cpp \ diff --git a/src/tools/qthreadinstance_p.h b/src/tools/qthreadinstance_p.h deleted file mode 100644 index 076c2ba19..000000000 --- a/src/tools/qthreadinstance_p.h +++ /dev/null @@ -1,111 +0,0 @@ -/**************************************************************************** -** -** ... -** -** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. -** -** 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. -** -**********************************************************************/ - -#ifndef TQTHREAD_P_H -#define TQTHREAD_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the TQt API. It exists for the convenience -// of TQThread and TQThreadStorage. This header file may change from -// version to version without notice, or even be removed. -// -// We mean it. -// -// - -#ifdef TQT_THREAD_SUPPORT - -#ifndef QT_H -#include "ntqmutex.h" -#include "ntqwindowdefs.h" -#endif // QT_H - -#ifdef Q_OS_UNIX -#include -#endif - -class TQThread; -class TQEventLoop; - -class TQThreadInstance { -public: - static void setCurrentThread(TQThread *thread); - static TQThreadInstance *current(); - - void init(unsigned int stackSize); - void deinit(); - - TQMutex *mutex() const; - void terminate(); - - unsigned int stacksize; - void *args[2]; - void **thread_storage; - bool finished : 1; - bool running : 1; - bool orphan : 1; - -#ifdef Q_OS_UNIX - pthread_cond_t thread_done; - pthread_t thread_id; - - static void *start( void * ); - static void finish( void * ); -#endif // Q_OS_UNIX - -#ifdef Q_OS_WIN32 - TQt::HANDLE handle; - unsigned int thread_id; - int waiters; - - static unsigned int __stdcall start( void * ); - static void finish( TQThreadInstance * ); -#endif // Q_OS_WIN32 - - static void finishGuiThread( TQThreadInstance *d ); - - TQEventLoop* eventLoop; - int cleanupType; - bool disableThreadPostedEvents : 1; -}; - -#endif // TQT_THREAD_SUPPORT -#endif // TQTHREAD_P_H diff --git a/src/tools/qthreadstorage_unix.cpp b/src/tools/qthreadstorage_unix.cpp deleted file mode 100644 index 86192868e..000000000 --- a/src/tools/qthreadstorage_unix.cpp +++ /dev/null @@ -1,366 +0,0 @@ -/**************************************************************************** -** -** ... -** -** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. -** -** 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. -** -**********************************************************************/ - -#ifdef TQT_THREAD_SUPPORT - -#include "ntqapplication.h" -#include "ntqthread.h" -#include "qplatformdefs.h" - -#include "ntqthreadstorage.h" -#include - -#include - -// #define TQTHREADSTORAGE_DEBUG - - -// keep this in sync with the implementation in qthreadstorage.cpp -static const int MAX_THREAD_STORAGE = 257; // 256 maximum + 1 used in TQRegExp - -static pthread_mutex_t thread_storage_mutex = PTHREAD_MUTEX_INITIALIZER; - -static bool thread_storage_init = FALSE; -static struct { - bool used; - void (*func)( void * ); -} thread_storage_usage[MAX_THREAD_STORAGE]; - - -TQThreadStorageData::TQThreadStorageData( void (*func)( void * ) ) - : id( 0 ) -{ - pthread_mutex_lock( &thread_storage_mutex ); - - // make sure things are initialized - if ( ! thread_storage_init ) - memset( thread_storage_usage, 0, sizeof( thread_storage_usage ) ); - thread_storage_init = TRUE; - - for ( ; id < MAX_THREAD_STORAGE; ++id ) { - if ( !thread_storage_usage[id].used ) - break; - } - - Q_ASSERT( id >= 0 && id < MAX_THREAD_STORAGE ); - thread_storage_usage[id].used = TRUE; - thread_storage_usage[id].func = func; - -#ifdef TQTHREADSTORAGE_DEBUG - tqDebug( "TQThreadStorageData: allocated id %d", id ); -#endif // TQTHREADSTORAGE_DEBUG - - pthread_mutex_unlock( &thread_storage_mutex ); -} - -TQThreadStorageData::~TQThreadStorageData() -{ - // The Gui thread has static storage duration, TQThreadStorage are almost always static (it's - // technically possible to allocate those in the heap, but it's quite unusual). It's impossible - // to predict whichever of those one gets destroyed first, but usually it's a TQThreadStorage. - // In that case we have to do the cleanup of its storage ourself as it won't be possible after - // nullifying the destructor below. - TQThread *guiThread = TQApplication::guiThread(); - if (guiThread) { - TQThreadInstance *d = guiThread->d; - TQMutexLocker locker( d->mutex() ); - if (d->thread_storage && d->thread_storage[id]) { - thread_storage_usage[id].func( d->thread_storage[id] ); - d->thread_storage[id] = nullptr; - } - } - - pthread_mutex_lock( &thread_storage_mutex ); - thread_storage_usage[id].used = FALSE; - thread_storage_usage[id].func = 0; - -#ifdef TQTHREADSTORAGE_DEBUG - tqDebug( "TQThreadStorageData: released id %d", id ); -#endif // TQTHREADSTORAGE_DEBUG - - pthread_mutex_unlock( &thread_storage_mutex ); -} - -void **TQThreadStorageData::get() const -{ - TQThreadInstance *d = TQThreadInstance::current(); - if (!d) { - tqWarning("TQThreadStorage can only be used with threads started with TQThread"); - return 0; - } - TQMutexLocker locker( d->mutex() ); - return d->thread_storage && d->thread_storage[id] ? &d->thread_storage[id] : 0; -} - -void **TQThreadStorageData::set( void *p ) -{ - TQThreadInstance *d = TQThreadInstance::current(); - if (!d) { - tqWarning("TQThreadStorage can only be used with threads started with TQThread"); - return 0; - } - TQMutexLocker locker( d->mutex() ); - if ( !d->thread_storage ) { -#ifdef TQTHREADSTORAGE_DEBUG - tqDebug( "TQThreadStorageData: allocating storage for thread %lx", - (unsigned long) pthread_self() ); -#endif // TQTHREADSTORAGE_DEBUG - - d->thread_storage = new void*[MAX_THREAD_STORAGE]; - memset( d->thread_storage, 0, sizeof( void* ) * MAX_THREAD_STORAGE ); - } - - // delete any previous data - if ( d->thread_storage[id] ) - thread_storage_usage[id].func( d->thread_storage[id] ); - - // store new data - d->thread_storage[id] = p; - return &d->thread_storage[id]; -} - -void TQThreadStorageData::finish( void **thread_storage ) -{ - if ( ! thread_storage ) return; // nothing to do - -#ifdef TQTHREADSTORAGE_DEBUG - tqDebug( "TQThreadStorageData: destroying storage for thread %lx", - (unsigned long) pthread_self() ); -#endif // TQTHREADSTORAGE_DEBUG - - for ( int i = 0; i < MAX_THREAD_STORAGE; ++i ) { - if ( ! thread_storage[i] ) continue; - if ( ! thread_storage_usage[i].used ) { -#ifdef QT_CHECK_STATE - tqWarning( "TQThreadStorage: thread %lx exited after TQThreadStorage destroyed", - (unsigned long) pthread_self() ); -#endif // QT_CHECK_STATE - continue; - } - - thread_storage_usage[i].func( thread_storage[i] ); - } - - delete [] thread_storage; -} - - -/*! - \class TQThreadStorage - \brief The TQThreadStorage class provides per-thread data storage. - - \threadsafe - \ingroup thread - \ingroup environment - - TQThreadStorage is a template class that provides per-thread data - storage. - - \e{Note that due to compiler limitations, TQThreadStorage can only - store pointers.} - - The setLocalData() function stores a single thread-specific value - for the calling thread. The data can be accessed later using the - localData() functions. TQThreadStorage takes ownership of the - data (which must be created on the heap with \e new) and deletes - it when the thread exits (either normally or via termination). - - The hasLocalData() function allows the programmer to determine if - data has previously been set using the setLocalData() function. - This is useful for lazy initializiation. - - For example, the following code uses TQThreadStorage to store a - single cache for each thread that calls the \e cacheObject() and - \e removeFromCache() functions. The cache is automatically - deleted when the calling thread exits (either normally or via - termination). - - \code - TQThreadStorage *> caches; - - void cacheObject( const TQString &key, SomeClass *object ) - { - if ( ! caches.hasLocalData() ) - caches.setLocalData( new TQCache ); - - caches.localData()->insert( key, object ); - } - - void removeFromCache( const TQString &key ) - { - if ( ! caches.hasLocalData() ) - return; // nothing to do - - caches.localData()->remove( key ); - } - \endcode - - \section1 Caveats - - \list - - \i As noted above, TQThreadStorage can only store pointers due to - compiler limitations. Support for value-based objects will be - added when the majority of compilers are able to support partial - template specialization. - - \i The \link ~TQThreadStorage() destructor\endlink does \e not - delete per-thread data. TQThreadStorage only deletes per-thread - data when the thread exits or when setLocalData() is called - multiple times. - - \i TQThreadStorage can only be used with threads started with - TQThread. It \e cannot be used with threads started with - platform-specific APIs. - - \i As a corollary to the above, platform-specific APIs cannot be - used to exit or terminate a TQThread using TQThreadStorage. Doing so - will cause all per-thread data to be leaked. See TQThread::exit() - and TQThread::terminate(). - - \i TQThreadStorage \e can be used to store data for the \e main() - thread \e after TQApplication has been constructed. TQThreadStorage - deletes all data set for the \e main() thread when TQApplication is - destroyed, regardless of whether or not the \e main() thread has - actually finished. - - \i The implementation of TQThreadStorage limits the total number of - TQThreadStorage objects to 256. An unlimited number of threads - can store per-thread data in each TQThreadStorage object. - - \endlist -*/ - -/*! - \fn TQThreadStorage::TQThreadStorage() - - Constructs a new per-thread data storage object. -*/ - -/*! - \fn TQThreadStorage::~TQThreadStorage() - - Destroys the per-thread data storage object. - - Note: The per-thread data stored is \e not deleted. Any data left - in TQThreadStorage is leaked. Make sure that all threads using - TQThreadStorage have exited before deleting the TQThreadStorage. - - \sa hasLocalData() -*/ - -/*! - \fn bool TQThreadStorage::hasLocalData() const - - Returns TRUE if the calling thread has non-zero data available; - otherwise returns FALSE. - - \sa localData() -*/ - -/*! - \fn T& TQThreadStorage::localData() - - Returns a reference to the data that was set by the calling - thread. - - Note: TQThreadStorage can only store pointers. This function - returns a \e reference to the pointer that was set by the calling - thread. The value of this reference is 0 if no data was set by - the calling thread, - - \sa hasLocalData() -*/ -/* - ### addition to the above documentation when we start supporting - ### partial template specialization, and TQThreadStorage can store - ### values *and* pointers - - When using TQThreadStorage to store values (not pointers), this - function stores an object of type \e T (created with its default - constructor) and returns a reference to that object. -*/ - -/*! - \fn const T TQThreadStorage::localData() const - \overload - - Returns a copy of the data that was set by the calling thread. - - Note: TQThreadStorage can only store pointers. This function - returns a pointer to the data that was set by the calling thread. - If no data was set by the calling thread, this function returns 0. - - \sa hasLocalData() -*/ -/* - ### addition to the above documentation when we start supporting - ### partial template specialization, and TQThreadStorage can store - ### values *and* pointers - - When using TQThreadStorage to store values (not pointers), this - function returns an object of type \e T (created with its default - constructor). Unlike the above function, this object is \e not - stored automatically. You will need to call setLocalData() to store - the object. -*/ - -/*! - \fn void TQThreadStorage::setLocalData( T data ) - - Sets the local data for the calling thread to \a data. It can be - accessed later using the localData() functions. - - If \a data is 0, this function deletes the previous data (if - any) and returns immediately. - - If \a data is non-zero, TQThreadStorage takes ownership of the \a - data and deletes it automatically either when the thread exits - (either normally or via termination) or when setLocalData() is - called again. - - Note: TQThreadStorage can only store pointers. The \a data - argument must be either a pointer to an object created on the heap - (i.e. using \e new) or 0. You should not delete \a data - yourself; TQThreadStorage takes ownership and will delete the \a - data itself. - - \sa localData() hasLocalData() -*/ - -#endif // TQT_THREAD_SUPPORT diff --git a/src/tools/qwaitcondition_unix.cpp b/src/tools/qwaitcondition_unix.cpp deleted file mode 100644 index 62038bae5..000000000 --- a/src/tools/qwaitcondition_unix.cpp +++ /dev/null @@ -1,316 +0,0 @@ -/**************************************************************************** -** -** TQWaitCondition class for Unix -** -** Created : 20010725 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** 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 "qplatformdefs.h" - -typedef pthread_mutex_t Q_MUTEX_T; - -#include "ntqwaitcondition.h" -#include "ntqmutex.h" -#include "qmutex_p.h" - -#include -#include - - -struct TQWaitConditionPrivate { - pthread_cond_t cond; -}; - - -/*! - \class TQWaitCondition ntqwaitcondition.h - \threadsafe - \brief The TQWaitCondition class allows waiting/waking for conditions between threads. - - \ingroup thread - \ingroup environment - - TQWaitConditions allow a thread to tell other threads that some - sort of condition has been met; one or many threads can block - waiting for a TQWaitCondition to set a condition with wakeOne() or - wakeAll(). Use wakeOne() to wake one randomly selected event or - wakeAll() to wake them all. For example, say we have three tasks - that should be performed every time the user presses a key; each - task could be split into a thread, each of which would have a - run() body like this: - - \code - TQWaitCondition key_pressed; - - for (;;) { - key_pressed.wait(); // This is a TQWaitCondition global variable - // Key was pressed, do something interesting - do_something(); - } - \endcode - - A fourth thread would read key presses and wake the other three - threads up every time it receives one, like this: - - \code - TQWaitCondition key_pressed; - - for (;;) { - getchar(); - // Causes any thread in key_pressed.wait() to return from - // that method and continue processing - key_pressed.wakeAll(); - } - \endcode - - Note that the order the three threads are woken up in is - undefined, and that if some or all of the threads are still in - do_something() when the key is pressed, they won't be woken up - (since they're not waiting on the condition variable) and so the - task will not be performed for that key press. This can be - avoided by, for example, doing something like this: - - \code - TQMutex mymutex; - TQWaitCondition key_pressed; - int mycount=0; - - // Worker thread code - for (;;) { - key_pressed.wait(); // This is a TQWaitCondition global variable - mymutex.lock(); - mycount++; - mymutex.unlock(); - do_something(); - mymutex.lock(); - mycount--; - mymutex.unlock(); - } - - // Key reading thread code - for (;;) { - getchar(); - mymutex.lock(); - // Sleep until there are no busy worker threads - while( mycount > 0 ) { - mymutex.unlock(); - sleep( 1 ); - mymutex.lock(); - } - mymutex.unlock(); - key_pressed.wakeAll(); - } - \endcode - - The mutexes are necessary because the results of two threads - attempting to change the value of the same variable simultaneously - are unpredictable. -*/ - -/*! - Constructs a new event signalling, i.e. wait condition, object. -*/ -TQWaitCondition::TQWaitCondition() -{ - d = new TQWaitConditionPrivate; - - int ret = pthread_cond_init(&d->cond, NULL); - -#ifdef QT_CHECK_RANGE - if (ret) - tqWarning( "Wait condition init failure: %s", strerror( ret ) ); -#endif -} - - -/*! - Deletes the event signalling, i.e. wait condition, object. -*/ -TQWaitCondition::~TQWaitCondition() -{ - int ret = pthread_cond_destroy(&d->cond); - - if (ret) { -#ifdef QT_CHECK_RANGE - tqWarning( "Wait condition destroy failure: %s", strerror( ret ) ); -#endif - - // seems we have threads waiting on us, lets wake them up - pthread_cond_broadcast(&d->cond); - } - - delete d; -} - -/*! - This wakes one thread waiting on the TQWaitCondition. The thread - that is woken up depends on the operating system's scheduling - policies, and cannot be controlled or predicted. - - \sa wakeAll() -*/ -void TQWaitCondition::wakeOne() -{ - int ret = pthread_cond_signal(&d->cond); - -#ifdef QT_CHECK_RANGE - if (ret) - tqWarning("Wait condition wakeOne failure: %s", strerror(ret)); -#endif -} - -/*! - This wakes all threads waiting on the TQWaitCondition. The order in - which the threads are woken up depends on the operating system's - scheduling policies, and cannot be controlled or predicted. - - \sa wakeOne() -*/ -void TQWaitCondition::wakeAll() -{ - int ret = pthread_cond_broadcast(&d->cond); - -#ifdef QT_CHECK_RANGE - if (ret) - tqWarning("Wait condition wakeAll failure: %s", strerror(ret)); -#endif -} - -/*! - Wait on the thread event object. The thread calling this will - block until either of these conditions is met: - \list - \i Another thread signals it using wakeOne() or wakeAll(). This - function will return TRUE in this case. - \i \a time milliseconds has elapsed. If \a time is ULONG_MAX (the - default), then the wait will never timeout (the event must be - signalled). This function will return FALSE if the wait timed - out. - \endlist - - \sa wakeOne(), wakeAll() -*/ -bool TQWaitCondition::wait(unsigned long time) -{ - static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; - pthread_mutex_lock( &mutex ); - - int ret; - if (time != ULONG_MAX) { - struct timeval tv; - gettimeofday(&tv, 0); - - timespec ti; - ti.tv_nsec = ( tv.tv_usec + ( time % 1000 ) * 1000 ) * 1000; - ti.tv_sec = tv.tv_sec + (time / 1000) + ( ti.tv_nsec / 1000000000 ); - ti.tv_nsec %= 1000000000; - - ret = pthread_cond_timedwait(&d->cond, &mutex, &ti); - } else - ret = pthread_cond_wait(&d->cond, &mutex); - -#ifdef QT_CHECK_RANGE - if (ret && ret != ETIMEDOUT) - tqWarning("Wait condition wait failure: %s",strerror(ret)); -#endif - - pthread_mutex_unlock( &mutex ); - - return (ret == 0); -} - -/*! - \overload - - Release the locked \a mutex and wait on the thread event object. - The \a mutex must be initially locked by the calling thread. If \a - mutex is not in a locked state, this function returns immediately. - If \a mutex is a recursive mutex, this function returns - immediately. The \a mutex will be unlocked, and the calling thread - will block until either of these conditions is met: - \list - \i Another thread signals it using wakeOne() or wakeAll(). This - function will return TRUE in this case. - \i \a time milliseconds has elapsed. If \a time is ULONG_MAX (the - default), then the wait will never timeout (the event must be - signalled). This function will return FALSE if the wait timed - out. - \endlist - - The mutex will be returned to the same locked state. This function - is provided to allow the atomic transition from the locked state - to the wait state. - - \sa wakeOne(), wakeAll() -*/ -bool TQWaitCondition::wait(TQMutex *mutex, unsigned long time) -{ - if (! mutex) - return FALSE; - - if (mutex->d->type() == Q_MUTEX_RECURSIVE) { -#ifdef QT_CHECK_RANGE - tqWarning("Wait condition warning: using recursive mutexes with\n" - " wait conditions is undefined!"); -#endif - return FALSE; - } - - int ret; - if (time != ULONG_MAX) { - struct timeval tv; - gettimeofday(&tv, 0); - - timespec ti; - ti.tv_nsec = ( tv.tv_usec + ( time % 1000 ) * 1000 ) * 1000; - ti.tv_sec = tv.tv_sec + (time / 1000) + ( ti.tv_nsec / 1000000000 ); - ti.tv_nsec %= 1000000000; - - ret = pthread_cond_timedwait(&d->cond, &mutex->d->handle, &ti); - } else - ret = pthread_cond_wait(&d->cond, &mutex->d->handle); - -#ifdef QT_CHECK_RANGE - if (ret && ret != ETIMEDOUT) - tqWarning("Wait condition wait failure: %s",strerror(ret)); -#endif - - return (ret == 0); -} - -#endif // TQT_THREAD_SUPPORT diff --git a/src/tools/tqmutex.h b/src/tools/tqmutex.h new file mode 100644 index 000000000..c517c6355 --- /dev/null +++ b/src/tools/tqmutex.h @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** Definition of TQMutex class +** +** Created : 931107 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** 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. +** +**********************************************************************/ + +#ifndef TQMUTEX_H +#define TQMUTEX_H + +#ifndef QT_H +#include "ntqglobal.h" +#endif // QT_H + +#if defined(TQT_THREAD_SUPPORT) + +class TQMutexPrivate; + +const int Q_MUTEX_NORMAL = 0; +const int Q_MUTEX_RECURSIVE = 1; + +class TQ_EXPORT TQMutex +{ + friend class TQThread; + friend class TQWaitCondition; + friend class TQWaitConditionPrivate; + +public: + TQMutex(bool recursive = FALSE); + virtual ~TQMutex(); + + void lock(); + void unlock(); + bool locked(); + bool tryLock(); + +private: + TQMutexPrivate * d; + +#if defined(TQ_DISABLE_COPY) + TQMutex( const TQMutex & ); + TQMutex &operator=( const TQMutex & ); +#endif + +public: + int level(); +}; + +class TQ_EXPORT TQMutexLocker +{ +public: + TQMutexLocker( TQMutex * ); + ~TQMutexLocker(); + + TQMutex *mutex() const; + +private: + TQMutex *mtx; + +#if defined(TQ_DISABLE_COPY) + TQMutexLocker( const TQMutexLocker & ); + TQMutexLocker &operator=( const TQMutexLocker & ); +#endif +}; + +inline TQMutexLocker::TQMutexLocker( TQMutex *m ) + : mtx( m ) +{ + if ( mtx ) mtx->lock(); +} + +inline TQMutexLocker::~TQMutexLocker() +{ + if ( mtx ) mtx->unlock(); +} + +inline TQMutex *TQMutexLocker::mutex() const +{ + return mtx; +} + +#endif + +#endif diff --git a/src/tools/tqmutex_p.h b/src/tools/tqmutex_p.h new file mode 100644 index 000000000..ee841f5e2 --- /dev/null +++ b/src/tools/tqmutex_p.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** TQMutex private class declarations +** +** Created : 20012507 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** 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. +** +**********************************************************************/ + +#ifndef TQMUTEX_P_H +#define TQMUTEX_P_H + +#ifndef QT_H +#endif // QT_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the TQt API. It exists for the convenience +// of tqmutex_unix.cpp and tqmutex_win.cpp. This header file may change +// from version to version without notice, or even be removed. +// +// We mean it. +// + +class TQMutexPrivate { +public: + // Q_MUTEX_T is defined in the various *.cpp files + Q_MUTEX_T handle; + + virtual ~TQMutexPrivate(); + + virtual void lock() = 0; + virtual void unlock() = 0; + virtual bool locked() = 0; + virtual bool trylock() = 0; + virtual int type() const = 0; + virtual int level() = 0; +}; + + +#endif // TQMUTEX_P_H diff --git a/src/tools/tqmutex_unix.cpp b/src/tools/tqmutex_unix.cpp new file mode 100644 index 000000000..9c793a02d --- /dev/null +++ b/src/tools/tqmutex_unix.cpp @@ -0,0 +1,535 @@ +/**************************************************************************** +** +** TQMutex class for Unix +** +** Created : 20010725 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** 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 "qplatformdefs.h" + +typedef pthread_mutex_t Q_MUTEX_T; + +#if defined(QT_CHECK_RANGE) +# define Q_NORMAL_MUTEX_TYPE PTHREAD_MUTEX_ERRORCHECK +#else +# define Q_NORMAL_MUTEX_TYPE PTHREAD_MUTEX_DEFAULT +#endif +#define Q_RECURSIVE_MUTEX_TYPE PTHREAD_MUTEX_RECURSIVE + +#include "tqmutex.h" +#include "tqmutex_p.h" + +#include +#include + +// Private class declarations + +class TQRealMutexPrivate : public TQMutexPrivate { +public: + TQRealMutexPrivate(bool = FALSE); + + void lock(); + void unlock(); + bool locked(); + bool trylock(); + int type() const; + int level(); + + bool recursive; + int count; +}; + + +// Private class implementation + +// base destructor +TQMutexPrivate::~TQMutexPrivate() +{ + int ret = pthread_mutex_destroy(&handle); + +#ifdef QT_CHECK_RANGE + if ( ret ) + tqWarning( "Mutex destroy failure: %s", strerror( ret ) ); +#endif +} + +// real mutex class +TQRealMutexPrivate::TQRealMutexPrivate(bool recurs) + : recursive(recurs), count(0) +{ + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, recursive ? Q_RECURSIVE_MUTEX_TYPE : Q_NORMAL_MUTEX_TYPE); + int ret = pthread_mutex_init(&handle, &attr); + pthread_mutexattr_destroy(&attr); + +#ifdef QT_CHECK_RANGE + if( ret ) + tqWarning( "Mutex init failure: %s", strerror( ret ) ); +#endif // QT_CHECK_RANGE +} + +void TQRealMutexPrivate::lock() +{ + int ret = pthread_mutex_lock(&handle); + + if (!ret) { + count++; + } else { +#ifdef QT_CHECK_RANGE + tqWarning("Mutex lock failure: %s", strerror(ret)); +#endif + } +} + +void TQRealMutexPrivate::unlock() +{ + count--; + int ret = pthread_mutex_unlock(&handle); + + if (ret) { + count++; +#ifdef QT_CHECK_RANGE + tqWarning("Mutex unlock failure: %s", strerror(ret)); +#endif + } +} + +bool TQRealMutexPrivate::locked() +{ + return count > 0; +} + +bool TQRealMutexPrivate::trylock() +{ + int ret = pthread_mutex_trylock(&handle); + + if (ret == EBUSY) { + return FALSE; + } else if (ret) { +#ifdef QT_CHECK_RANGE + tqWarning("Mutex trylock failure: %s", strerror(ret)); +#endif + return FALSE; + } + + return TRUE; +} + +int TQRealMutexPrivate::type() const +{ + return recursive ? Q_MUTEX_RECURSIVE : Q_MUTEX_NORMAL; +} + +int TQRealMutexPrivate::level() +{ + return count; +} + + +/*! + \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) +{ + 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(); +} + +/*! + Returns the current lock level of the mutex. + 0 means the mutex is unlocked + This method should only be called when the mutex has already been locked + by lock(), otherwise the lock level could change before the next line + of code is executed. + + WARNING: Non-recursive mutexes will never exceed a lock level of 1! + + \sa lock(), unlock(), locked() +*/ +int TQMutex::level() +{ + return d->level(); +} + +/*! + \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 diff --git a/src/tools/tqmutexpool.cpp b/src/tools/tqmutexpool.cpp new file mode 100644 index 000000000..a7b17da3d --- /dev/null +++ b/src/tools/tqmutexpool.cpp @@ -0,0 +1,155 @@ +/**************************************************************************** +** +** ... +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** 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. +** +**********************************************************************/ + +#include "tqmutexpool_p.h" + +#ifdef TQT_THREAD_SUPPORT + +#include + +TQ_EXPORT TQMutexPool *tqt_global_mutexpool = 0; + + +/*! + \class TQMutexPool tqmutexpool_p.h + \brief The TQMutexPool class provides a pool of TQMutex objects. + + \internal + + \ingroup thread + + TQMutexPool is a convenience class that provides access to a fixed + number of TQMutex objects. + + Typical use of a TQMutexPool is in situations where it is not + possible or feasible to use one TQMutex for every protected object. + The mutex pool will return a mutex based on the address of the + object that needs protection. + + For example, consider this simple class: + + \code + class Number { + public: + Number( double n ) : num ( n ) { } + + void setNumber( double n ) { num = n; } + double number() const { return num; } + + private: + double num; + }; + \endcode + + Adding a TQMutex member to the Number class does not make sense, + because it is so small. However, in order to ensure that access to + each Number is protected, you need to use a mutex. In this case, a + TQMutexPool would be ideal. + + Code to calculate the square of a number would then look something + like this: + + \code + void calcSquare( Number *num ) + { + TQMutexLocker locker( mutexpool.get( num ) ); + num.setNumber( num.number() * num.number() ); + } + \endcode + + This function will safely calculate the square of a number, since + it uses a mutex from a TQMutexPool. The mutex is locked and + unlocked automatically by the TQMutexLocker class. See the + TQMutexLocker documentation for more details. +*/ + +/*! + Constructs a TQMutexPool, reserving space for \a size TQMutexes. If + \a recursive is TRUE, all TQMutexes in the pool will be recursive + mutexes; otherwise they will all be non-recursive (the default). + + The TQMutexes are created when needed, and deleted when the + TQMutexPool is destructed. +*/ +TQMutexPool::TQMutexPool( bool recursive, int size ) + : mutex( FALSE ), count( size ), recurs( recursive ) +{ + mutexes = new TQMutex*[count]; + for ( int index = 0; index < count; ++index ) { + mutexes[index] = 0; + } +} + +/*! + Destructs a TQMutexPool. All TQMutexes that were created by the pool + are deleted. +*/ +TQMutexPool::~TQMutexPool() +{ + TQMutexLocker locker( &mutex ); + for ( int index = 0; index < count; ++index ) { + delete mutexes[index]; + mutexes[index] = 0; + } + delete [] mutexes; + mutexes = 0; +} + +/*! + Returns a TQMutex from the pool. TQMutexPool uses the value \a + address to determine which mutex is retured from the pool. +*/ +TQMutex *TQMutexPool::get( void *address ) +{ + int index = (int) ( (unsigned long) address % count ); + + if ( ! mutexes[index] ) { + // mutex not created, create one + + TQMutexLocker locker( &mutex ); + // we need to check once again that the mutex hasn't been created, since + // 2 threads could be trying to create a mutex as the same index... + if ( ! mutexes[index] ) { + mutexes[index] = new TQMutex( recurs ); + } + } + + return mutexes[index]; +} + +#endif diff --git a/src/tools/tqmutexpool_p.h b/src/tools/tqmutexpool_p.h new file mode 100644 index 000000000..28a7ac63a --- /dev/null +++ b/src/tools/tqmutexpool_p.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** ... +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** 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. +** +**********************************************************************/ + +#ifndef TQMUTEXPOOL_P_H +#define TQMUTEXPOOL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the TQt API. It exists for the convenience +// of TQSettings. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// +// + +#ifdef TQT_THREAD_SUPPORT + +#ifndef QT_H +#include "tqmutex.h" +#include "ntqmemarray.h" +#endif // QT_H + +class TQ_EXPORT TQMutexPool +{ +public: + TQMutexPool( bool recursive = FALSE, int size = 17 ); + ~TQMutexPool(); + + TQMutex *get( void *address ); + +private: + TQMutex mutex; + TQMutex **mutexes; + int count; + bool recurs; +}; + +extern TQ_EXPORT TQMutexPool *tqt_global_mutexpool; + +#endif // TQT_THREAD_SUPPORT + +#endif // TQMUTEXPOOL_P_H diff --git a/src/tools/tqsemaphore.cpp b/src/tools/tqsemaphore.cpp new file mode 100644 index 000000000..a5cdfc630 --- /dev/null +++ b/src/tools/tqsemaphore.cpp @@ -0,0 +1,255 @@ +/**************************************************************************** +** +** TQSemaphore class for Unix +** +** Created : 20010725 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** 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 "tqsemaphore.h" +#include "tqmutex.h" +#include "tqwaitcondition.h" + + +/*! + \class TQSemaphore tqsemaphore.h + \threadsafe + \brief The TQSemaphore class provides a robust integer semaphore. + + \ingroup thread + \ingroup environment + + A TQSemaphore can be used to serialize thread execution, in a + similar way to a TQMutex. A semaphore differs from a mutex, in + that a semaphore can be accessed by more than one thread at a + time. + + For example, suppose we have an application that stores data in a + large tree structure. The application creates 10 threads + (commonly called a thread pool) to perform searches on the tree. + When the application searches the tree for some piece of data, it + uses one thread per base node to do the searching. A semaphore + could be used to make sure that two threads don't try to search + the same branch of the tree at the same time. + + A non-computing example of a semaphore would be dining at a + restuarant. A semaphore is initialized to have a maximum count + equal to the number of chairs in the restuarant. As people + arrive, they want a seat. As seats are filled, the semaphore is + accessed, once per person. As people leave, the access is + released, allowing more people to enter. If a party of 10 people + want to be seated, but there are only 9 seats, those 10 people + will wait, but a party of 4 people would be seated (taking the + available seats to 5, making the party of 10 people wait longer). + + When a semaphore is created it is given a number which is the + maximum number of concurrent accesses it will permit. Accesses to + the sempahore are gained using operator++() or operator+=(), and + released with operator--() or operator-=(). The number of + accesses allowed is retrieved with available(), and the total + number with total(). Note that the incrementing functions will + block if there aren't enough available accesses. Use tryAccess() + if you want to acquire accesses without blocking. +*/ + + +class TQSemaphorePrivate { +public: + TQSemaphorePrivate(int); + + TQMutex mutex; + TQWaitCondition cond; + + int value, max; +}; + + +TQSemaphorePrivate::TQSemaphorePrivate(int m) + : mutex(FALSE), value(0), max(m) +{ +} + + +/*! + Creates a new semaphore. The semaphore can be concurrently + accessed at most \a maxcount times. +*/ +TQSemaphore::TQSemaphore(int maxcount) +{ + d = new TQSemaphorePrivate(maxcount); +} + + +/*! + Destroys the semaphore. + + \warning If you destroy a semaphore that has accesses in use the + resultant behavior is undefined. +*/ +TQSemaphore::~TQSemaphore() +{ + delete d; +} + + +/*! + Postfix ++ operator. + + Try to get access to the semaphore. If \l available() == 0, this + call will block until it can get access, i.e. until available() \> + 0. +*/ +int TQSemaphore::operator++(int) +{ + TQMutexLocker locker(&d->mutex); + while (d->value >= d->max) + d->cond.wait(locker.mutex()); + + ++d->value; + if (d->value > d->max) + d->value = d->max; + + return d->value; +} + + +/*! + Postfix -- operator. + + Release access of the semaphore. This wakes all threads waiting + for access to the semaphore. +*/ +int TQSemaphore::operator--(int) +{ + TQMutexLocker locker(&d->mutex); + + --d->value; + if (d->value < 0) + d->value = 0; + + d->cond.wakeAll(); + + return d->value; +} + + +/*! + Try to get access to the semaphore. If \l available() \< \a n, this + call will block until it can get all the accesses it wants, i.e. + until available() \>= \a n. +*/ +int TQSemaphore::operator+=(int n) +{ + TQMutexLocker locker(&d->mutex); + + if ( n < 0 || n > d->max ) { +#ifdef QT_CHECK_RANGE + tqWarning( "TQSemaphore::operator+=: paramter %d out of range", n ); +#endif // QT_CHECK_RANGE + n = n < 0 ? 0 : d->max; + } + + while (d->value + n > d->max) + d->cond.wait(locker.mutex()); + + d->value += n; + + return d->value; +} + + +/*! + Release \a n accesses to the semaphore. +*/ +int TQSemaphore::operator-=(int n) +{ + TQMutexLocker locker(&d->mutex); + + if ( n < 0 || n > d->value ) { +#ifdef QT_CHECK_RANGE + tqWarning( "TQSemaphore::operator-=: paramter %d out of range", n ); +#endif // QT_CHECK_RANGE + n = n < 0 ? 0 : d->value; + } + + d->value -= n; + d->cond.wakeAll(); + + return d->value; +} + + +/*! + Returns the number of accesses currently available to the + semaphore. +*/ +int TQSemaphore::available() const +{ + TQMutexLocker locker(&d->mutex); + return d->max - d->value; +} + + +/*! + Returns the total number of accesses to the semaphore. +*/ +int TQSemaphore::total() const +{ + TQMutexLocker locker(&d->mutex); + return d->max; +} + + +/*! + Try to get access to the semaphore. If \l available() \< \a n, this + function will return FALSE immediately. If \l available() \>= \a n, + this function will take \a n accesses and return TRUE. This + function does \e not block. +*/ +bool TQSemaphore::tryAccess(int n) +{ + TQMutexLocker locker(&d->mutex); + + if (d->value + n > d->max) + return FALSE; + + d->value += n; + + return TRUE; +} + +#endif // TQT_THREAD_SUPPORT diff --git a/src/tools/tqsemaphore.h b/src/tools/tqsemaphore.h new file mode 100644 index 000000000..0dc8e81de --- /dev/null +++ b/src/tools/tqsemaphore.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Definition of TQSemaphore class +** +** Created : 931107 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** 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. +** +**********************************************************************/ + +#ifndef TQSEMAPHORE_H +#define TQSEMAPHORE_H + +#ifndef QT_H +#include "ntqglobal.h" +#endif // QT_H + +#if defined(TQT_THREAD_SUPPORT) + +class TQSemaphorePrivate; + +class TQ_EXPORT TQSemaphore +{ +public: + TQSemaphore( int ); + virtual ~TQSemaphore(); + + int available() const; + int total() const; + + // postfix operators + int operator++(int); + int operator--(int); + + int operator+=(int); + int operator-=(int); + + bool tryAccess(int); + +private: + TQSemaphorePrivate *d; + +#if defined(TQ_DISABLE_COPY) + TQSemaphore(const TQSemaphore &); + TQSemaphore &operator=(const TQSemaphore &); +#endif +}; + +#endif + +#endif diff --git a/src/tools/tqstring.cpp b/src/tools/tqstring.cpp index dbf179404..71eced17d 100644 --- a/src/tools/tqstring.cpp +++ b/src/tools/tqstring.cpp @@ -94,7 +94,7 @@ #endif #if defined(TQT_THREAD_SUPPORT) && defined(MAKE_QSTRING_THREAD_SAFE) -#include "ntqmutex.h" +#include "tqmutex.h" #endif // TQT_THREAD_SUPPORT && MAKE_QSTRING_THREAD_SAFE extern TQMutex *tqt_sharedStringMutex; diff --git a/src/tools/tqthreadinstance_p.h b/src/tools/tqthreadinstance_p.h new file mode 100644 index 000000000..1cc0d083e --- /dev/null +++ b/src/tools/tqthreadinstance_p.h @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** ... +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** 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. +** +**********************************************************************/ + +#ifndef TQTHREAD_P_H +#define TQTHREAD_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the TQt API. It exists for the convenience +// of TQThread and TQThreadStorage. This header file may change from +// version to version without notice, or even be removed. +// +// We mean it. +// +// + +#ifdef TQT_THREAD_SUPPORT + +#ifndef QT_H +#include "tqmutex.h" +#include "ntqwindowdefs.h" +#endif // QT_H + +#ifdef Q_OS_UNIX +#include +#endif + +class TQThread; +class TQEventLoop; + +class TQThreadInstance { +public: + static void setCurrentThread(TQThread *thread); + static TQThreadInstance *current(); + + void init(unsigned int stackSize); + void deinit(); + + TQMutex *mutex() const; + void terminate(); + + unsigned int stacksize; + void *args[2]; + void **thread_storage; + bool finished : 1; + bool running : 1; + bool orphan : 1; + +#ifdef Q_OS_UNIX + pthread_cond_t thread_done; + pthread_t thread_id; + + static void *start( void * ); + static void finish( void * ); +#endif // Q_OS_UNIX + +#ifdef Q_OS_WIN32 + TQt::HANDLE handle; + unsigned int thread_id; + int waiters; + + static unsigned int __stdcall start( void * ); + static void finish( TQThreadInstance * ); +#endif // Q_OS_WIN32 + + static void finishGuiThread( TQThreadInstance *d ); + + TQEventLoop* eventLoop; + int cleanupType; + bool disableThreadPostedEvents : 1; +}; + +#endif // TQT_THREAD_SUPPORT +#endif // TQTHREAD_P_H diff --git a/src/tools/tqthreadstorage.h b/src/tools/tqthreadstorage.h new file mode 100644 index 000000000..588621237 --- /dev/null +++ b/src/tools/tqthreadstorage.h @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** ... +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** 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. +** +**********************************************************************/ + +#ifndef TQTHREADSTORAGE_H +#define TQTHREADSTORAGE_H + +#ifdef TQT_THREAD_SUPPORT + +#ifndef QT_H +#include "ntqglobal.h" +#endif // QT_H + +class TQ_EXPORT TQThreadStorageData +{ +public: + TQThreadStorageData( void (*func)(void *) ); + ~TQThreadStorageData(); + + void** get() const; + void** set( void* p ); + + static void finish( void** ); + int id; +}; + + +template +class TQThreadStorage +{ +private: + TQThreadStorageData d; + +#if defined(TQ_DISABLE_COPY) + // disable copy constructor and operator= + TQThreadStorage( const TQThreadStorage & ); + TQThreadStorage &operator=( const TQThreadStorage & ); +#endif // TQ_DISABLE_COPY + + static void deleteData( void *x ) { delete (T)x; } + +public: + inline TQThreadStorage() : d( deleteData ) { } + inline ~TQThreadStorage() { } + + inline bool hasLocalData() const + { return d.get() != 0; } + + inline T& localData() + { void **v = d.get(); if ( !v ) v = d.set( 0 ); return *(T*)v; } + + inline T localData() const + { void **v = d.get(); return ( v ? *(T*)v : 0 ); } + + inline void setLocalData( T t ) + { (void) d.set( t ); } +}; + +#endif // TQT_THREAD_SUPPORT + +#endif // TQTHREADSTORAGE_H diff --git a/src/tools/tqthreadstorage_unix.cpp b/src/tools/tqthreadstorage_unix.cpp new file mode 100644 index 000000000..9a7e179b2 --- /dev/null +++ b/src/tools/tqthreadstorage_unix.cpp @@ -0,0 +1,366 @@ +/**************************************************************************** +** +** ... +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** 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. +** +**********************************************************************/ + +#ifdef TQT_THREAD_SUPPORT + +#include "ntqapplication.h" +#include "tqthread.h" +#include "qplatformdefs.h" + +#include "tqthreadstorage.h" +#include + +#include + +// #define TQTHREADSTORAGE_DEBUG + + +// keep this in sync with the implementation in tqthreadstorage.cpp +static const int MAX_THREAD_STORAGE = 257; // 256 maximum + 1 used in TQRegExp + +static pthread_mutex_t thread_storage_mutex = PTHREAD_MUTEX_INITIALIZER; + +static bool thread_storage_init = FALSE; +static struct { + bool used; + void (*func)( void * ); +} thread_storage_usage[MAX_THREAD_STORAGE]; + + +TQThreadStorageData::TQThreadStorageData( void (*func)( void * ) ) + : id( 0 ) +{ + pthread_mutex_lock( &thread_storage_mutex ); + + // make sure things are initialized + if ( ! thread_storage_init ) + memset( thread_storage_usage, 0, sizeof( thread_storage_usage ) ); + thread_storage_init = TRUE; + + for ( ; id < MAX_THREAD_STORAGE; ++id ) { + if ( !thread_storage_usage[id].used ) + break; + } + + Q_ASSERT( id >= 0 && id < MAX_THREAD_STORAGE ); + thread_storage_usage[id].used = TRUE; + thread_storage_usage[id].func = func; + +#ifdef TQTHREADSTORAGE_DEBUG + tqDebug( "TQThreadStorageData: allocated id %d", id ); +#endif // TQTHREADSTORAGE_DEBUG + + pthread_mutex_unlock( &thread_storage_mutex ); +} + +TQThreadStorageData::~TQThreadStorageData() +{ + // The Gui thread has static storage duration, TQThreadStorage are almost always static (it's + // technically possible to allocate those in the heap, but it's quite unusual). It's impossible + // to predict whichever of those one gets destroyed first, but usually it's a TQThreadStorage. + // In that case we have to do the cleanup of its storage ourself as it won't be possible after + // nullifying the destructor below. + TQThread *guiThread = TQApplication::guiThread(); + if (guiThread) { + TQThreadInstance *d = guiThread->d; + TQMutexLocker locker( d->mutex() ); + if (d->thread_storage && d->thread_storage[id]) { + thread_storage_usage[id].func( d->thread_storage[id] ); + d->thread_storage[id] = nullptr; + } + } + + pthread_mutex_lock( &thread_storage_mutex ); + thread_storage_usage[id].used = FALSE; + thread_storage_usage[id].func = 0; + +#ifdef TQTHREADSTORAGE_DEBUG + tqDebug( "TQThreadStorageData: released id %d", id ); +#endif // TQTHREADSTORAGE_DEBUG + + pthread_mutex_unlock( &thread_storage_mutex ); +} + +void **TQThreadStorageData::get() const +{ + TQThreadInstance *d = TQThreadInstance::current(); + if (!d) { + tqWarning("TQThreadStorage can only be used with threads started with TQThread"); + return 0; + } + TQMutexLocker locker( d->mutex() ); + return d->thread_storage && d->thread_storage[id] ? &d->thread_storage[id] : 0; +} + +void **TQThreadStorageData::set( void *p ) +{ + TQThreadInstance *d = TQThreadInstance::current(); + if (!d) { + tqWarning("TQThreadStorage can only be used with threads started with TQThread"); + return 0; + } + TQMutexLocker locker( d->mutex() ); + if ( !d->thread_storage ) { +#ifdef TQTHREADSTORAGE_DEBUG + tqDebug( "TQThreadStorageData: allocating storage for thread %lx", + (unsigned long) pthread_self() ); +#endif // TQTHREADSTORAGE_DEBUG + + d->thread_storage = new void*[MAX_THREAD_STORAGE]; + memset( d->thread_storage, 0, sizeof( void* ) * MAX_THREAD_STORAGE ); + } + + // delete any previous data + if ( d->thread_storage[id] ) + thread_storage_usage[id].func( d->thread_storage[id] ); + + // store new data + d->thread_storage[id] = p; + return &d->thread_storage[id]; +} + +void TQThreadStorageData::finish( void **thread_storage ) +{ + if ( ! thread_storage ) return; // nothing to do + +#ifdef TQTHREADSTORAGE_DEBUG + tqDebug( "TQThreadStorageData: destroying storage for thread %lx", + (unsigned long) pthread_self() ); +#endif // TQTHREADSTORAGE_DEBUG + + for ( int i = 0; i < MAX_THREAD_STORAGE; ++i ) { + if ( ! thread_storage[i] ) continue; + if ( ! thread_storage_usage[i].used ) { +#ifdef QT_CHECK_STATE + tqWarning( "TQThreadStorage: thread %lx exited after TQThreadStorage destroyed", + (unsigned long) pthread_self() ); +#endif // QT_CHECK_STATE + continue; + } + + thread_storage_usage[i].func( thread_storage[i] ); + } + + delete [] thread_storage; +} + + +/*! + \class TQThreadStorage + \brief The TQThreadStorage class provides per-thread data storage. + + \threadsafe + \ingroup thread + \ingroup environment + + TQThreadStorage is a template class that provides per-thread data + storage. + + \e{Note that due to compiler limitations, TQThreadStorage can only + store pointers.} + + The setLocalData() function stores a single thread-specific value + for the calling thread. The data can be accessed later using the + localData() functions. TQThreadStorage takes ownership of the + data (which must be created on the heap with \e new) and deletes + it when the thread exits (either normally or via termination). + + The hasLocalData() function allows the programmer to determine if + data has previously been set using the setLocalData() function. + This is useful for lazy initializiation. + + For example, the following code uses TQThreadStorage to store a + single cache for each thread that calls the \e cacheObject() and + \e removeFromCache() functions. The cache is automatically + deleted when the calling thread exits (either normally or via + termination). + + \code + TQThreadStorage *> caches; + + void cacheObject( const TQString &key, SomeClass *object ) + { + if ( ! caches.hasLocalData() ) + caches.setLocalData( new TQCache ); + + caches.localData()->insert( key, object ); + } + + void removeFromCache( const TQString &key ) + { + if ( ! caches.hasLocalData() ) + return; // nothing to do + + caches.localData()->remove( key ); + } + \endcode + + \section1 Caveats + + \list + + \i As noted above, TQThreadStorage can only store pointers due to + compiler limitations. Support for value-based objects will be + added when the majority of compilers are able to support partial + template specialization. + + \i The \link ~TQThreadStorage() destructor\endlink does \e not + delete per-thread data. TQThreadStorage only deletes per-thread + data when the thread exits or when setLocalData() is called + multiple times. + + \i TQThreadStorage can only be used with threads started with + TQThread. It \e cannot be used with threads started with + platform-specific APIs. + + \i As a corollary to the above, platform-specific APIs cannot be + used to exit or terminate a TQThread using TQThreadStorage. Doing so + will cause all per-thread data to be leaked. See TQThread::exit() + and TQThread::terminate(). + + \i TQThreadStorage \e can be used to store data for the \e main() + thread \e after TQApplication has been constructed. TQThreadStorage + deletes all data set for the \e main() thread when TQApplication is + destroyed, regardless of whether or not the \e main() thread has + actually finished. + + \i The implementation of TQThreadStorage limits the total number of + TQThreadStorage objects to 256. An unlimited number of threads + can store per-thread data in each TQThreadStorage object. + + \endlist +*/ + +/*! + \fn TQThreadStorage::TQThreadStorage() + + Constructs a new per-thread data storage object. +*/ + +/*! + \fn TQThreadStorage::~TQThreadStorage() + + Destroys the per-thread data storage object. + + Note: The per-thread data stored is \e not deleted. Any data left + in TQThreadStorage is leaked. Make sure that all threads using + TQThreadStorage have exited before deleting the TQThreadStorage. + + \sa hasLocalData() +*/ + +/*! + \fn bool TQThreadStorage::hasLocalData() const + + Returns TRUE if the calling thread has non-zero data available; + otherwise returns FALSE. + + \sa localData() +*/ + +/*! + \fn T& TQThreadStorage::localData() + + Returns a reference to the data that was set by the calling + thread. + + Note: TQThreadStorage can only store pointers. This function + returns a \e reference to the pointer that was set by the calling + thread. The value of this reference is 0 if no data was set by + the calling thread, + + \sa hasLocalData() +*/ +/* + ### addition to the above documentation when we start supporting + ### partial template specialization, and TQThreadStorage can store + ### values *and* pointers + + When using TQThreadStorage to store values (not pointers), this + function stores an object of type \e T (created with its default + constructor) and returns a reference to that object. +*/ + +/*! + \fn const T TQThreadStorage::localData() const + \overload + + Returns a copy of the data that was set by the calling thread. + + Note: TQThreadStorage can only store pointers. This function + returns a pointer to the data that was set by the calling thread. + If no data was set by the calling thread, this function returns 0. + + \sa hasLocalData() +*/ +/* + ### addition to the above documentation when we start supporting + ### partial template specialization, and TQThreadStorage can store + ### values *and* pointers + + When using TQThreadStorage to store values (not pointers), this + function returns an object of type \e T (created with its default + constructor). Unlike the above function, this object is \e not + stored automatically. You will need to call setLocalData() to store + the object. +*/ + +/*! + \fn void TQThreadStorage::setLocalData( T data ) + + Sets the local data for the calling thread to \a data. It can be + accessed later using the localData() functions. + + If \a data is 0, this function deletes the previous data (if + any) and returns immediately. + + If \a data is non-zero, TQThreadStorage takes ownership of the \a + data and deletes it automatically either when the thread exits + (either normally or via termination) or when setLocalData() is + called again. + + Note: TQThreadStorage can only store pointers. The \a data + argument must be either a pointer to an object created on the heap + (i.e. using \e new) or 0. You should not delete \a data + yourself; TQThreadStorage takes ownership and will delete the \a + data itself. + + \sa localData() hasLocalData() +*/ + +#endif // TQT_THREAD_SUPPORT diff --git a/src/tools/tqwaitcondition.h b/src/tools/tqwaitcondition.h new file mode 100644 index 000000000..503d5d6c9 --- /dev/null +++ b/src/tools/tqwaitcondition.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Definition of TQWaitCondition class +** +** Created : 931107 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** 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. +** +**********************************************************************/ + +#ifndef TQWAITCONDITION_H +#define TQWAITCONDITION_H + +#ifndef QT_H +#include "ntqglobal.h" +#endif // QT_H + +#if defined(TQT_THREAD_SUPPORT) + +#include + +class TQWaitConditionPrivate; +class TQMutex; + +class TQ_EXPORT TQWaitCondition +{ +public: + TQWaitCondition(); + virtual ~TQWaitCondition(); + + // default argument causes thread to block indefinately + bool wait( unsigned long time = ULONG_MAX ); + bool wait( TQMutex *mutex, unsigned long time = ULONG_MAX ); + + void wakeOne(); + void wakeAll(); + +private: + TQWaitConditionPrivate * d; + +#if defined(TQ_DISABLE_COPY) + TQWaitCondition( const TQWaitCondition & ); + TQWaitCondition &operator=( const TQWaitCondition & ); +#endif +}; + +#endif + +#endif diff --git a/src/tools/tqwaitcondition_unix.cpp b/src/tools/tqwaitcondition_unix.cpp new file mode 100644 index 000000000..78fdb16bc --- /dev/null +++ b/src/tools/tqwaitcondition_unix.cpp @@ -0,0 +1,316 @@ +/**************************************************************************** +** +** TQWaitCondition class for Unix +** +** Created : 20010725 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** 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 "qplatformdefs.h" + +typedef pthread_mutex_t Q_MUTEX_T; + +#include "tqwaitcondition.h" +#include "tqmutex.h" +#include "tqmutex_p.h" + +#include +#include + + +struct TQWaitConditionPrivate { + pthread_cond_t cond; +}; + + +/*! + \class TQWaitCondition tqwaitcondition.h + \threadsafe + \brief The TQWaitCondition class allows waiting/waking for conditions between threads. + + \ingroup thread + \ingroup environment + + TQWaitConditions allow a thread to tell other threads that some + sort of condition has been met; one or many threads can block + waiting for a TQWaitCondition to set a condition with wakeOne() or + wakeAll(). Use wakeOne() to wake one randomly selected event or + wakeAll() to wake them all. For example, say we have three tasks + that should be performed every time the user presses a key; each + task could be split into a thread, each of which would have a + run() body like this: + + \code + TQWaitCondition key_pressed; + + for (;;) { + key_pressed.wait(); // This is a TQWaitCondition global variable + // Key was pressed, do something interesting + do_something(); + } + \endcode + + A fourth thread would read key presses and wake the other three + threads up every time it receives one, like this: + + \code + TQWaitCondition key_pressed; + + for (;;) { + getchar(); + // Causes any thread in key_pressed.wait() to return from + // that method and continue processing + key_pressed.wakeAll(); + } + \endcode + + Note that the order the three threads are woken up in is + undefined, and that if some or all of the threads are still in + do_something() when the key is pressed, they won't be woken up + (since they're not waiting on the condition variable) and so the + task will not be performed for that key press. This can be + avoided by, for example, doing something like this: + + \code + TQMutex mymutex; + TQWaitCondition key_pressed; + int mycount=0; + + // Worker thread code + for (;;) { + key_pressed.wait(); // This is a TQWaitCondition global variable + mymutex.lock(); + mycount++; + mymutex.unlock(); + do_something(); + mymutex.lock(); + mycount--; + mymutex.unlock(); + } + + // Key reading thread code + for (;;) { + getchar(); + mymutex.lock(); + // Sleep until there are no busy worker threads + while( mycount > 0 ) { + mymutex.unlock(); + sleep( 1 ); + mymutex.lock(); + } + mymutex.unlock(); + key_pressed.wakeAll(); + } + \endcode + + The mutexes are necessary because the results of two threads + attempting to change the value of the same variable simultaneously + are unpredictable. +*/ + +/*! + Constructs a new event signalling, i.e. wait condition, object. +*/ +TQWaitCondition::TQWaitCondition() +{ + d = new TQWaitConditionPrivate; + + int ret = pthread_cond_init(&d->cond, NULL); + +#ifdef QT_CHECK_RANGE + if (ret) + tqWarning( "Wait condition init failure: %s", strerror( ret ) ); +#endif +} + + +/*! + Deletes the event signalling, i.e. wait condition, object. +*/ +TQWaitCondition::~TQWaitCondition() +{ + int ret = pthread_cond_destroy(&d->cond); + + if (ret) { +#ifdef QT_CHECK_RANGE + tqWarning( "Wait condition destroy failure: %s", strerror( ret ) ); +#endif + + // seems we have threads waiting on us, lets wake them up + pthread_cond_broadcast(&d->cond); + } + + delete d; +} + +/*! + This wakes one thread waiting on the TQWaitCondition. The thread + that is woken up depends on the operating system's scheduling + policies, and cannot be controlled or predicted. + + \sa wakeAll() +*/ +void TQWaitCondition::wakeOne() +{ + int ret = pthread_cond_signal(&d->cond); + +#ifdef QT_CHECK_RANGE + if (ret) + tqWarning("Wait condition wakeOne failure: %s", strerror(ret)); +#endif +} + +/*! + This wakes all threads waiting on the TQWaitCondition. The order in + which the threads are woken up depends on the operating system's + scheduling policies, and cannot be controlled or predicted. + + \sa wakeOne() +*/ +void TQWaitCondition::wakeAll() +{ + int ret = pthread_cond_broadcast(&d->cond); + +#ifdef QT_CHECK_RANGE + if (ret) + tqWarning("Wait condition wakeAll failure: %s", strerror(ret)); +#endif +} + +/*! + Wait on the thread event object. The thread calling this will + block until either of these conditions is met: + \list + \i Another thread signals it using wakeOne() or wakeAll(). This + function will return TRUE in this case. + \i \a time milliseconds has elapsed. If \a time is ULONG_MAX (the + default), then the wait will never timeout (the event must be + signalled). This function will return FALSE if the wait timed + out. + \endlist + + \sa wakeOne(), wakeAll() +*/ +bool TQWaitCondition::wait(unsigned long time) +{ + static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + pthread_mutex_lock( &mutex ); + + int ret; + if (time != ULONG_MAX) { + struct timeval tv; + gettimeofday(&tv, 0); + + timespec ti; + ti.tv_nsec = ( tv.tv_usec + ( time % 1000 ) * 1000 ) * 1000; + ti.tv_sec = tv.tv_sec + (time / 1000) + ( ti.tv_nsec / 1000000000 ); + ti.tv_nsec %= 1000000000; + + ret = pthread_cond_timedwait(&d->cond, &mutex, &ti); + } else + ret = pthread_cond_wait(&d->cond, &mutex); + +#ifdef QT_CHECK_RANGE + if (ret && ret != ETIMEDOUT) + tqWarning("Wait condition wait failure: %s",strerror(ret)); +#endif + + pthread_mutex_unlock( &mutex ); + + return (ret == 0); +} + +/*! + \overload + + Release the locked \a mutex and wait on the thread event object. + The \a mutex must be initially locked by the calling thread. If \a + mutex is not in a locked state, this function returns immediately. + If \a mutex is a recursive mutex, this function returns + immediately. The \a mutex will be unlocked, and the calling thread + will block until either of these conditions is met: + \list + \i Another thread signals it using wakeOne() or wakeAll(). This + function will return TRUE in this case. + \i \a time milliseconds has elapsed. If \a time is ULONG_MAX (the + default), then the wait will never timeout (the event must be + signalled). This function will return FALSE if the wait timed + out. + \endlist + + The mutex will be returned to the same locked state. This function + is provided to allow the atomic transition from the locked state + to the wait state. + + \sa wakeOne(), wakeAll() +*/ +bool TQWaitCondition::wait(TQMutex *mutex, unsigned long time) +{ + if (! mutex) + return FALSE; + + if (mutex->d->type() == Q_MUTEX_RECURSIVE) { +#ifdef QT_CHECK_RANGE + tqWarning("Wait condition warning: using recursive mutexes with\n" + " wait conditions is undefined!"); +#endif + return FALSE; + } + + int ret; + if (time != ULONG_MAX) { + struct timeval tv; + gettimeofday(&tv, 0); + + timespec ti; + ti.tv_nsec = ( tv.tv_usec + ( time % 1000 ) * 1000 ) * 1000; + ti.tv_sec = tv.tv_sec + (time / 1000) + ( ti.tv_nsec / 1000000000 ); + ti.tv_nsec %= 1000000000; + + ret = pthread_cond_timedwait(&d->cond, &mutex->d->handle, &ti); + } else + ret = pthread_cond_wait(&d->cond, &mutex->d->handle); + +#ifdef QT_CHECK_RANGE + if (ret && ret != ETIMEDOUT) + tqWarning("Wait condition wait failure: %s",strerror(ret)); +#endif + + return (ret == 0); +} + +#endif // TQT_THREAD_SUPPORT -- cgit v1.2.3