author | simon <simon> | 2002-12-10 11:07:46 (UTC) |
---|---|---|
committer | simon <simon> | 2002-12-10 11:07:46 (UTC) |
commit | f468c3bc69655aefa0ec5783405355dd3dde4afc (patch) (side-by-side diff) | |
tree | b358fb36cb4547a0bf2c100573e4846fbc32211c | |
parent | 448426777d9e35826898791d03b4bc71335427ff (diff) | |
download | opie-f468c3bc69655aefa0ec5783405355dd3dde4afc.zip opie-f468c3bc69655aefa0ec5783405355dd3dde4afc.tar.gz opie-f468c3bc69655aefa0ec5783405355dd3dde4afc.tar.bz2 |
- added ThreadUtil::Thread class
-rw-r--r-- | noncore/multimedia/opieplayer2/threadutil.cpp | 99 | ||||
-rw-r--r-- | noncore/multimedia/opieplayer2/threadutil.h | 28 |
2 files changed, 127 insertions, 0 deletions
diff --git a/noncore/multimedia/opieplayer2/threadutil.cpp b/noncore/multimedia/opieplayer2/threadutil.cpp index 4055c74..5687f42 100644 --- a/noncore/multimedia/opieplayer2/threadutil.cpp +++ b/noncore/multimedia/opieplayer2/threadutil.cpp @@ -25,4 +25,5 @@ #include <assert.h> #include <unistd.h> +#include <errno.h> using namespace ThreadUtil; @@ -123,4 +124,102 @@ void WaitCondition::wakeAll() } +struct Thread::Data +{ + Data() : isRunning( false ) + {} + + pthread_t self; + Mutex guard; + bool isRunning; + + WaitCondition finishCondition; +}; + +extern "C" +{ + +void _threadutil_terminate_thread( void *arg ) +{ + Thread *thr = ( Thread* )arg; + + assert( thr ); + + AutoLock locker( thr->d->guard ); + thr->d->isRunning = false; + thr->d->finishCondition.wakeAll(); +} + +void *_threadutil_start_thread( void *arg ) +{ + Thread *thr = ( Thread* )arg; + + pthread_cleanup_push( _threadutil_terminate_thread, thr ); + + thr->d->isRunning = true; + thr->run(); + + pthread_cleanup_pop( true ); + + Thread::exit(); + return 0; // never reached +} + +} + +Thread::Thread() + : d( new Data ) +{ +} + +Thread::~Thread() +{ + assert( d->isRunning == false ); + delete d; +} + +void Thread::start() +{ + AutoLock lock( d->guard ); + + if ( d->isRunning ) { + qDebug( "ThreadUtil::Thread::start() called for running thread." ); + return; + } + + pthread_attr_t attributes; + pthread_attr_init( &attributes ); + pthread_attr_setscope( &attributes, PTHREAD_SCOPE_SYSTEM ); + int err = pthread_create( &d->self, &attributes, _threadutil_start_thread, ( void* )this ); + if ( err != 0 ) { + qDebug( "ThreadUtil::Thread::start() : can't create thread: %s", strerror( err ) ); + pthread_attr_destroy( &attributes ); + return; + } + pthread_attr_destroy( &attributes ); +} + +void Thread::terminate() +{ + AutoLock lock( d->guard ); + if ( !d->isRunning ) + return; + + pthread_cancel( d->self ); +} + +bool Thread::wait() +{ + AutoLock lock( d->guard ); + if ( !d->isRunning ) + return true; + + return d->finishCondition.wait( d->guard ); +} + +void Thread::exit() +{ + pthread_exit( 0 ); +} + OnewayNotifier::OnewayNotifier() { diff --git a/noncore/multimedia/opieplayer2/threadutil.h b/noncore/multimedia/opieplayer2/threadutil.h index 5cc4cdc..b537cc1 100644 --- a/noncore/multimedia/opieplayer2/threadutil.h +++ b/noncore/multimedia/opieplayer2/threadutil.h @@ -27,4 +27,10 @@ class QSocketNotifier; +extern "C" +{ + void *_threadutil_start_thread( void* ); + void _threadutil_terminate_thread( void* ); +} + namespace ThreadUtil { @@ -82,4 +88,26 @@ namespace ThreadUtil }; + class Thread + { + friend void *::_threadutil_start_thread( void* ); + friend void ::_threadutil_terminate_thread( void* ); + public: + Thread(); + virtual ~Thread(); + + void start(); + void terminate(); + + bool wait(); + + static void exit(); + protected: + virtual void run() = 0; + + private: + struct Data; + Data *d; + }; + class OnewayNotifier : public QObject { |