summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--noncore/multimedia/opieplayer2/threadutil.cpp99
-rw-r--r--noncore/multimedia/opieplayer2/threadutil.h28
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
@@ -24,6 +24,7 @@
24#include <pthread.h> 24#include <pthread.h>
25#include <assert.h> 25#include <assert.h>
26#include <unistd.h> 26#include <unistd.h>
27#include <errno.h>
27 28
28using namespace ThreadUtil; 29using namespace ThreadUtil;
29 30
@@ -122,6 +123,104 @@ void WaitCondition::wakeAll()
122 pthread_cond_broadcast( &d->waitCondition ); 123 pthread_cond_broadcast( &d->waitCondition );
123} 124}
124 125
126struct Thread::Data
127{
128 Data() : isRunning( false )
129 {}
130
131 pthread_t self;
132 Mutex guard;
133 bool isRunning;
134
135 WaitCondition finishCondition;
136};
137
138extern "C"
139{
140
141void _threadutil_terminate_thread( void *arg )
142{
143 Thread *thr = ( Thread* )arg;
144
145 assert( thr );
146
147 AutoLock locker( thr->d->guard );
148 thr->d->isRunning = false;
149 thr->d->finishCondition.wakeAll();
150}
151
152void *_threadutil_start_thread( void *arg )
153{
154 Thread *thr = ( Thread* )arg;
155
156 pthread_cleanup_push( _threadutil_terminate_thread, thr );
157
158 thr->d->isRunning = true;
159 thr->run();
160
161 pthread_cleanup_pop( true );
162
163 Thread::exit();
164 return 0; // never reached
165}
166
167}
168
169Thread::Thread()
170 : d( new Data )
171{
172}
173
174Thread::~Thread()
175{
176 assert( d->isRunning == false );
177 delete d;
178}
179
180void Thread::start()
181{
182 AutoLock lock( d->guard );
183
184 if ( d->isRunning ) {
185 qDebug( "ThreadUtil::Thread::start() called for running thread." );
186 return;
187 }
188
189 pthread_attr_t attributes;
190 pthread_attr_init( &attributes );
191 pthread_attr_setscope( &attributes, PTHREAD_SCOPE_SYSTEM );
192 int err = pthread_create( &d->self, &attributes, _threadutil_start_thread, ( void* )this );
193 if ( err != 0 ) {
194 qDebug( "ThreadUtil::Thread::start() : can't create thread: %s", strerror( err ) );
195 pthread_attr_destroy( &attributes );
196 return;
197 }
198 pthread_attr_destroy( &attributes );
199}
200
201void Thread::terminate()
202{
203 AutoLock lock( d->guard );
204 if ( !d->isRunning )
205 return;
206
207 pthread_cancel( d->self );
208}
209
210bool Thread::wait()
211{
212 AutoLock lock( d->guard );
213 if ( !d->isRunning )
214 return true;
215
216 return d->finishCondition.wait( d->guard );
217}
218
219void Thread::exit()
220{
221 pthread_exit( 0 );
222}
223
125OnewayNotifier::OnewayNotifier() 224OnewayNotifier::OnewayNotifier()
126{ 225{
127 int fds[ 2 ]; 226 int fds[ 2 ];
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
@@ -26,6 +26,12 @@
26 26
27class QSocketNotifier; 27class QSocketNotifier;
28 28
29extern "C"
30{
31 void *_threadutil_start_thread( void* );
32 void _threadutil_terminate_thread( void* );
33}
34
29namespace ThreadUtil 35namespace ThreadUtil
30{ 36{
31 37
@@ -81,6 +87,28 @@ namespace ThreadUtil
81 WaitCondition &operator=( const WaitCondition & ); 87 WaitCondition &operator=( const WaitCondition & );
82 }; 88 };
83 89
90 class Thread
91 {
92 friend void *::_threadutil_start_thread( void* );
93 friend void ::_threadutil_terminate_thread( void* );
94 public:
95 Thread();
96 virtual ~Thread();
97
98 void start();
99 void terminate();
100
101 bool wait();
102
103 static void exit();
104 protected:
105 virtual void run() = 0;
106
107 private:
108 struct Data;
109 Data *d;
110 };
111
84 class OnewayNotifier : public QObject 112 class OnewayNotifier : public QObject
85 { 113 {
86 Q_OBJECT 114 Q_OBJECT