summaryrefslogtreecommitdiffstats
path: root/src/tsthread
diff options
context:
space:
mode:
Diffstat (limited to 'src/tsthread')
-rw-r--r--src/tsthread/Makefile.am12
-rw-r--r--src/tsthread/tsthread.cpp194
-rw-r--r--src/tsthread/tsthread.h387
-rw-r--r--src/tsthread/tswaitcondition.cpp60
-rw-r--r--src/tsthread/tswaitcondition.h72
5 files changed, 725 insertions, 0 deletions
diff --git a/src/tsthread/Makefile.am b/src/tsthread/Makefile.am
new file mode 100644
index 0000000..cd0ed32
--- /dev/null
+++ b/src/tsthread/Makefile.am
@@ -0,0 +1,12 @@
+INCLUDES = -I$(srcdir) -I$(srcdir)/.. $(all_includes)
+
+noinst_LTLIBRARIES = libtsthread.la
+
+libtsthread_la_SOURCES = \
+ tsthread.cpp \
+ tswaitcondition.cpp
+
+noinst_HEADERS = \
+ tsthread.h
+
+METASOURCES = AUTO
diff --git a/src/tsthread/tsthread.cpp b/src/tsthread/tsthread.cpp
new file mode 100644
index 0000000..16b4538
--- /dev/null
+++ b/src/tsthread/tsthread.cpp
@@ -0,0 +1,194 @@
+/****************************************************************************
+
+ Copyright (C) 2004 Lubos Lunak <l.lunak@kde.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
+****************************************************************************/
+
+#include "tsthread.h"
+
+#include <qapplication.h>
+#include <qmetaobject.h>
+#include <kdebug.h>
+#include <qguardedptr.h>
+
+#include <assert.h>
+
+#ifdef TS_QTHREADSTORAGE
+QThreadStorage< TSThread** >* TSThread::current_thread;
+#else
+TSCurrentThread* TSThread::current_thread;
+#endif
+TSThread* TSThread::main_thread = NULL;
+
+class TSMainThread
+ : public TSThread
+ {
+ protected:
+ virtual void run() { assert( false ); }
+ };
+
+TSThread::Helper::Helper( TSThread* parent )
+ : thread( parent )
+ {
+ assert( parent );
+ }
+
+void TSThread::Helper::run()
+ {
+ thread->executeThread();
+ }
+
+
+TSThread::TSThread()
+ : thread( this )
+ , cancelling( false )
+ , emit_pending( false )
+ , cancel_mutex( NULL )
+ , cancel_cond( NULL )
+ , deleted_flag( NULL )
+ {
+ }
+
+TSThread::~TSThread()
+ {
+ if( deleted_flag != NULL )
+ *deleted_flag = true;
+ }
+
+void TSThread::start()
+ {
+ if( current_thread == NULL )
+ initCurrentThread();
+ thread.start();
+ }
+
+void TSThread::cancel()
+ {
+ QMutexLocker lock( &mutex );
+ cancelling = true;
+ if( cancel_mutex != NULL )
+ {
+ QMutexLocker lock( cancel_mutex );
+ cancel_cond->wakeAll();
+ }
+ }
+
+void TSThread::wait( unsigned long time )
+ {
+ thread.wait( time );
+ }
+
+bool TSThread::finished() const
+ {
+ return thread.finished();
+ }
+
+bool TSThread::running() const
+ {
+ return thread.running();
+ }
+
+void TSThread::initCurrentThread()
+ {
+#ifdef TS_QTHREADSTORAGE
+ current_thread = new QThreadStorage< TSThread** >();
+ typedef TSThread* TSThreadPtr;
+ // set pointer for main thread (this must be main thread)
+ current_thread->setLocalData( new TSThreadPtr( NULL )); // TODO NULL ?
+#else
+ current_thread = new TSCurrentThread();
+ main_thread = new TSMainThread;
+ // set pointer for main thread (this must be main thread)
+ current_thread->setLocalData( main_thread );
+#endif
+ }
+
+void TSThread::executeThread()
+ {
+#ifdef TS_QTHREADSTORAGE
+ // store dynamically allocated pointer, so that
+ // QThreadStorage deletes the pointer and not TSThread
+ typedef TSThread* TSThreadPtr;
+ current_thread->setLocalData( new TSThreadPtr( this ));
+#else
+ current_thread->setLocalData( this );
+#endif
+ run();
+ postSignal( this, NULL ); // = terminated()
+ }
+
+void TSThread::postSignal( QObject* obj, const char* signal )
+ {
+ assert( currentThread() == this );
+ qApp->postEvent( this, new SignalEvent( signal, obj, NULL ));
+ }
+
+void TSThread::emitSignalInternal( QObject* obj, const char* signal, QUObject* o )
+ {
+ assert( currentThread() == this );
+ QMutexLocker locker( &signal_mutex );
+ emit_pending = true;
+ qApp->postEvent( this, new SignalEvent( signal, obj, o ));
+ while( emit_pending )
+ signal_cond.wait( &signal_mutex );
+ }
+
+void TSThread::emitCancellableSignalInternal( QObject* obj, const char* signal, QUObject* o )
+ {
+ assert( currentThread() == this );
+ // can't use this->mutex, because its locking will be triggered by TSWaitCondition
+ QMutexLocker locker( &signal_mutex );
+ emit_pending = true;
+ qApp->postEvent( this, new SignalEvent( signal, obj, o ));
+ while( emit_pending && !testCancel())
+ signal_cond.cancellableWait( &signal_mutex );
+ emit_pending = false; // in case of cancel
+ }
+
+void TSThread::customEvent( QCustomEvent* ev )
+ {
+ SignalEvent* e = static_cast< SignalEvent* >( ev );
+ if( e->signal.isEmpty()) // = terminated()
+ { // threadExecute() finishes before the actual thread terminates
+ if( !finished())
+ wait();
+ emit terminated();
+ return;
+ }
+ bool deleted = false;
+ deleted_flag = &deleted; // this is like QGuardedPtr for self, but faster
+ int signal_id = e->object->metaObject()->findSignal( normalizeSignalSlot( e->signal ).data() + 1, true );
+ if( signal_id >= 0 )
+ e->object->qt_emit( signal_id, e->args );
+ else
+ kdWarning() << "Cannot emit signal \"" << e->signal << "\"." << endl;
+ if( deleted ) // some slot deleted 'this'
+ return;
+ deleted_flag = NULL;
+ QMutexLocker locker( &signal_mutex );
+ if( emit_pending )
+ {
+ emit_pending = false;
+ signal_cond.wakeOne();
+ }
+ }
+
+#include "tsthread.moc"
diff --git a/src/tsthread/tsthread.h b/src/tsthread/tsthread.h
new file mode 100644
index 0000000..5b98890
--- /dev/null
+++ b/src/tsthread/tsthread.h
@@ -0,0 +1,387 @@
+/****************************************************************************
+
+ Copyright (C) 2004 Lubos Lunak <l.lunak@kde.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
+****************************************************************************/
+
+#ifndef TSTHREAD_H
+#define TSTHREAD_H
+
+#include <qobject.h>
+#include <qthread.h>
+#include <qwaitcondition.h>
+#include <qdeepcopy.h>
+#include <qmutex.h>
+#include <private/qucomextra_p.h>
+
+#ifdef TS_QTHREADSTORAGE
+#include <qthreadstorage.h>
+#else
+#include <pthread.h>
+#endif
+
+#include "tswaitcondition.h"
+
+// how difficult ...
+template< typename T >
+T TSDeepCopy( const T& t )
+{
+ return QDeepCopy< T >( t );
+}
+
+class TSCurrentThread;
+
+/**
+ Thread class, internally based on QThread, which intentionally doesn't have
+ dangerous crap like QThread::terminate() and intentionally has useful features
+ like emitting signals to the main thread, currentThread() or support
+ for cancelling.
+ */
+class TSThread
+ : public QObject
+ {
+ Q_OBJECT
+ public:
+ TSThread();
+ virtual ~TSThread();
+ /**
+ * Starts the thread.
+ * @see QThread::start()
+ */
+ void start();
+ /**
+ * Waits for the thread to finish.
+ * @see QThread::wait()
+ */
+ void wait( unsigned long time = ULONG_MAX );
+ /**
+ * Returns true if the thread has finished.
+ * @see QThread::finished()
+ */
+ bool finished() const;
+ /**
+ * Returns true if the thread is running.
+ * @see QThread::running()
+ */
+ bool running() const;
+ /**
+ * Sends the thread a request to terminate.
+ * The thread must check for cancellation using testCancel()
+ * and finish execution (return from run()).
+ * @see testCancel()
+ */
+ void cancel();
+ // TODO suspend + resume?
+ /**
+ * Returns true if a request to terminate is pending.
+ * @see cancel()
+ */
+ bool testCancel() const;
+ /**
+ * Returns pointer to the current thread, i.e. thread from which
+ * this function is called.
+ */
+ static TSThread* currentThread();
+ /**
+ * Returns a pointer to the main thread. Mostly useful for currentThread().
+ */
+ static TSThread* mainThread();
+ /**
+ * Emits the specified signal in the main thread. This function returns
+ * only after all slots connected to the signal have been executed (i.e.
+ * it works like normal signal). The signal can have one pointer argument,
+ * which can be used for communication in either direction. QObject::sender()
+ * in slots is valid.
+ * Example:
+ * \code
+ * emitSignal( this, SIGNAL( result( int* )), &result_data );
+ * \endcode
+ * @see postSignal
+ * @see emitCancellableSignal
+ */
+ void emitSignal( QObject* obj, const char* signal );
+ template< typename T1 >
+ void emitSignal( QObject* obj, const char* signal, const T1& p1 );
+ template< typename T1, typename T2 >
+ void emitSignal( QObject* obj, const char* signal, const T1& p1, const T2& p2 );
+ /**
+ * This function works like emitSignal(), but additionally acts as a cancellation
+ * point, i.e. calling cancel() on the thread causes premature return.
+ * @see emitSignal
+ * @see postSignal
+ */
+ void emitCancellableSignal( QObject* obj, const char* signal );
+ template< typename T1 >
+ void emitCancellableSignal( QObject* obj, const char* signal, const T1& p1 );
+ template< typename T1, typename T2 >
+ void emitCancellableSignal( QObject* obj, const char* signal, const T1& p1, const T2& p2 );
+ /**
+ * Posts (i.e. it is not executed immediatelly like normal signals)
+ * a signal to be emitted in the main thread. The signal cannot
+ * have any parameters, use your TSThread derived class instance
+ * data members instead. QObject::sender() in slots is valid, unless
+ * the thread instance is destroyed before the signal is processed.
+ * @see emitSignal
+ */
+ void postSignal( QObject* obj, const char* signal ); // is emitted _always_ in main thread
+ protected:
+ /**
+ * The code to be executed in the started thread.
+ * @see QThread::run()
+ */
+ virtual void run() = 0;
+ signals:
+ /**
+ * Emitted after the thread is terminated.
+ */
+ void terminated(); // is emitted _always_ in main thread
+ protected:
+ /**
+ * @internal
+ */
+ void customEvent( QCustomEvent* e );
+ private:
+ class SignalEvent
+ : public QCustomEvent
+ {
+ public:
+ SignalEvent( const char* sig, QObject* obj, QUObject* o )
+ : QCustomEvent( QEvent::User ), signal( sig ), object( obj ), args( o )
+ {
+ }
+ const QCString signal;
+ QObject* object;
+ QUObject* args;
+ };
+ class Helper
+ : public QThread
+ {
+ public:
+ Helper( TSThread* parent );
+ protected:
+ virtual void run();
+ private:
+ TSThread* thread;
+ };
+ void executeThread();
+ static void initCurrentThread();
+ bool setCancelData( QMutex*m, QWaitCondition* c );
+ void setSignalData( QUObject* o, int i );
+ void setSignalData( QUObject* o, const QImage& i );
+ void setSignalData( QUObject* o, const QString& s );
+ void setSignalData( QUObject* o, bool b );
+ void setSignalData( QUObject* o, const QColor& c );
+ void setSignalData( QUObject* o, const char* s );
+ void setSignalData( QUObject* o, const QSize& );
+ void emitSignalInternal( QObject* obj, const char* signal, QUObject* o );
+ void emitCancellableSignalInternal( QObject* obj, const char* signal, QUObject* o );
+ friend class Helper;
+ friend class TSWaitCondition;
+ Helper thread;
+ bool cancelling;
+ bool emit_pending;
+ mutable QMutex mutex;
+ QMutex signal_mutex;
+ TSWaitCondition signal_cond;
+ QMutex* cancel_mutex;
+ QWaitCondition* cancel_cond;
+ bool* deleted_flag;
+#ifdef TS_QTHREADSTORAGE
+ static QThreadStorage< TSThread** >* current_thread;
+#else
+ static TSCurrentThread* current_thread;
+#endif
+ static TSThread* main_thread;
+ private:
+ TSThread( const TSThread& );
+ TSThread& operator=( const TSThread& );
+ };
+
+#ifndef TS_QTHREADSTORAGE
+/**
+ * @internal
+ */
+class TSCurrentThread
+ {
+ public:
+ TSCurrentThread();
+ ~TSCurrentThread();
+ TSThread* localData() const;
+ void setLocalData( TSThread* t );
+ private:
+ pthread_key_t key;
+ };
+
+
+inline TSCurrentThread::TSCurrentThread()
+ {
+ pthread_key_create( &key, NULL );
+ }
+
+inline TSCurrentThread::~TSCurrentThread()
+ {
+ pthread_key_delete( key );
+ }
+
+inline void TSCurrentThread::setLocalData( TSThread* t )
+ {
+ pthread_setspecific( key, t );
+ }
+
+inline TSThread* TSCurrentThread::localData() const
+ {
+ return static_cast< TSThread* >( pthread_getspecific( key ));
+ }
+#endif
+
+inline
+bool TSThread::testCancel() const
+ {
+ QMutexLocker lock( &mutex );
+ return cancelling;
+ }
+
+#include <kdebug.h>
+inline
+bool TSThread::setCancelData( QMutex* m, QWaitCondition* c )
+ {
+ QMutexLocker lock( &mutex );
+ if( cancelling && m != NULL )
+ return false;
+ cancel_mutex = m;
+ cancel_cond = c;
+ return true;
+ }
+
+inline
+TSThread* TSThread::currentThread()
+ {
+ if( current_thread == NULL )
+ initCurrentThread();
+#ifdef TS_QTHREADSTORAGE
+ return *current_thread->localData();
+#else
+ return current_thread->localData();
+#endif
+ }
+
+inline
+TSThread* TSThread::mainThread()
+ {
+ return main_thread;
+ }
+
+inline
+void TSThread::setSignalData( QUObject* o, int i )
+ {
+ static_QUType_int.set( o, i );
+ }
+
+inline
+void TSThread::setSignalData( QUObject* o, const QImage& i )
+ {
+ static_QUType_varptr.set( o, &i );
+ }
+
+inline
+void TSThread::setSignalData( QUObject* o, const QString& s )
+ {
+ static_QUType_QString.set( o, s );
+ }
+
+inline
+void TSThread::setSignalData( QUObject* o, bool b )
+ {
+ static_QUType_bool.set( o, b );
+ }
+
+inline
+void TSThread::setSignalData( QUObject* o, const QColor& c )
+ {
+ static_QUType_varptr.set( o, &c );
+ }
+
+inline
+void TSThread::setSignalData( QUObject* o, const char* s )
+ {
+ static_QUType_charstar.set( o, s );
+ }
+
+inline
+void TSThread::setSignalData( QUObject* o, const QSize& s )
+ {
+ static_QUType_varptr.set( o, &s );
+ }
+
+inline
+void TSThread::emitSignal( QObject* obj, const char* signal )
+ {
+ QUObject o[ 1 ];
+ emitSignalInternal( obj, signal, o );
+ }
+
+template< typename T1 >
+inline
+void TSThread::emitSignal( QObject* obj, const char* signal, const T1& p1 )
+ {
+ QUObject o[ 2 ];
+ setSignalData( o + 1, p1 );
+ emitSignalInternal( obj, signal, o );
+ }
+
+template< typename T1, typename T2 >
+inline
+void TSThread::emitSignal( QObject* obj, const char* signal, const T1& p1, const T2& p2 )
+ {
+ QUObject o[ 3 ];
+ setSignalData( o + 1, p1 );
+ setSignalData( o + 2, p2 );
+ emitSignalInternal( obj, signal, o );
+ }
+
+inline
+void TSThread::emitCancellableSignal( QObject* obj, const char* signal )
+ {
+ QUObject o[ 1 ];
+ emitCancellableSignalInternal( obj, signal, o );
+ }
+
+template< typename T1 >
+inline
+void TSThread::emitCancellableSignal( QObject* obj, const char* signal, const T1& p1 )
+ {
+ QUObject o[ 2 ];
+ setSignalData( o + 1, p1 );
+ emitCancellableSignalInternal( obj, signal, o );
+ }
+
+template< typename T1, typename T2 >
+inline
+void TSThread::emitCancellableSignal( QObject* obj, const char* signal, const T1& p1, const T2& p2 )
+ {
+ QUObject o[ 3 ];
+ setSignalData( o + 1, p1 );
+ setSignalData( o + 2, p2 );
+ emitCancellableSignalInternal( obj, signal, o );
+ }
+
+
+#endif
diff --git a/src/tsthread/tswaitcondition.cpp b/src/tsthread/tswaitcondition.cpp
new file mode 100644
index 0000000..e11e989
--- /dev/null
+++ b/src/tsthread/tswaitcondition.cpp
@@ -0,0 +1,60 @@
+/****************************************************************************
+
+ Copyright (C) 2004 Lubos Lunak <l.lunak@kde.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
+****************************************************************************/
+
+#include "tswaitcondition.h"
+
+#include "tsthread.h"
+
+bool TSWaitCondition::wait( QMutex* m, unsigned long time )
+ {
+ return cond.wait( m, time ); // TODO?
+ }
+
+bool TSWaitCondition::cancellableWait( QMutex* m, unsigned long time )
+ {
+ mutex.lock();
+ if( !TSThread::currentThread()->setCancelData( &mutex, &cond ))
+ {
+ mutex.unlock();
+ return false;
+ }
+ m->unlock();
+ bool ret = cond.wait( &mutex, time );
+ TSThread::currentThread()->setCancelData( NULL, NULL );
+ mutex.unlock();
+ m->lock();
+ return ret;
+ }
+
+void TSWaitCondition::wakeOne()
+ {
+ QMutexLocker locker( &mutex );
+ cond.wakeOne();
+ }
+
+void TSWaitCondition::wakeAll()
+ {
+ QMutexLocker locker( &mutex );
+ cond.wakeAll();
+ }
diff --git a/src/tsthread/tswaitcondition.h b/src/tsthread/tswaitcondition.h
new file mode 100644
index 0000000..09f9cab
--- /dev/null
+++ b/src/tsthread/tswaitcondition.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+
+ Copyright (C) 2004 Lubos Lunak <l.lunak@kde.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
+****************************************************************************/
+
+#ifndef TSWAITCONDITION_H
+#define TSWAITCONDITION_H
+
+#include <qmutex.h>
+#include <qwaitcondition.h>
+
+class TSWaitCondition
+ {
+ public:
+ TSWaitCondition();
+ ~TSWaitCondition();
+ bool wait( QMutex* mutex, unsigned long time = ULONG_MAX );
+ bool wait( QMutex& mutex, unsigned long time = ULONG_MAX );
+ bool cancellableWait( QMutex* mutex, unsigned long time = ULONG_MAX );
+ bool cancellableWait( QMutex& mutex, unsigned long time = ULONG_MAX );
+ void wakeOne();
+ void wakeAll();
+ private:
+ QMutex mutex;
+ QWaitCondition cond;
+ private:
+ TSWaitCondition( const TSWaitCondition& );
+ TSWaitCondition& operator=( const TSWaitCondition& );
+ };
+
+inline
+TSWaitCondition::TSWaitCondition()
+ {
+ }
+
+inline
+TSWaitCondition::~TSWaitCondition()
+ {
+ }
+
+inline
+bool TSWaitCondition::wait( QMutex& mutex, unsigned long time )
+ {
+ return wait( &mutex, time );
+ }
+
+inline
+bool TSWaitCondition::cancellableWait( QMutex& mutex, unsigned long time )
+ {
+ return cancellableWait( &mutex, time );
+ }
+
+#endif