summaryrefslogtreecommitdiff
authorsimon <simon>2002-12-11 11:05:52 (UTC)
committer simon <simon>2002-12-11 11:05:52 (UTC)
commitdd7fcdf1589c8513055f6475d3a1f33075d971d8 (patch) (unidiff)
tree3b4927a023eea68d1c529b4852ce2cdd1801db49
parent616e7437498c7adcad77d9b79e9c450a75b260ca (diff)
downloadopie-dd7fcdf1589c8513055f6475d3a1f33075d971d8.zip
opie-dd7fcdf1589c8513055f6475d3a1f33075d971d8.tar.gz
opie-dd7fcdf1589c8513055f6475d3a1f33075d971d8.tar.bz2
- gcc2 is not my friend, given that it can't deal with friend declarations
properly :) (a.k.a: make it compile with gcc2, step 2)
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/multimedia/opieplayer2/threadutil.cpp17
-rw-r--r--noncore/multimedia/opieplayer2/threadutil.h6
2 files changed, 11 insertions, 12 deletions
diff --git a/noncore/multimedia/opieplayer2/threadutil.cpp b/noncore/multimedia/opieplayer2/threadutil.cpp
index 7a9e1a4..ff38b1e 100644
--- a/noncore/multimedia/opieplayer2/threadutil.cpp
+++ b/noncore/multimedia/opieplayer2/threadutil.cpp
@@ -1,389 +1,394 @@
1/* This file is part of the KDE project 1/* This file is part of the KDE project
2 Copyright (C) 2002 Simon Hausmann <hausmann@kde.org> 2 Copyright (C) 2002 Simon Hausmann <hausmann@kde.org>
3 3
4 This library is free software; you can redistribute it and/or 4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public 5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either 6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version. 7 version 2 of the License, or (at your option) any later version.
8 8
9 This library is distributed in the hope that it will be useful, 9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of 10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details. 12 Library General Public License for more details.
13 13
14 You should have received a copy of the GNU Library General Public License 14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to 15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 16 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA. 17 Boston, MA 02111-1307, USA.
18*/ 18*/
19 19
20#include "threadutil.h" 20#include "threadutil.h"
21 21
22#include <qsocketnotifier.h> 22#include <qsocketnotifier.h>
23 23
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#include <errno.h>
28 28
29using namespace ThreadUtil; 29using namespace ThreadUtil;
30 30
31struct Mutex::Data 31struct Mutex::Data
32{ 32{
33 Data() 33 Data()
34 { 34 {
35 pthread_mutex_init( &mutex, 0 ); 35 pthread_mutex_init( &mutex, 0 );
36 } 36 }
37 ~Data() 37 ~Data()
38 { 38 {
39 pthread_mutex_destroy( &mutex ); 39 pthread_mutex_destroy( &mutex );
40 } 40 }
41 41
42 pthread_mutex_t mutex; 42 pthread_mutex_t mutex;
43}; 43};
44 44
45Mutex::Mutex() 45Mutex::Mutex()
46 : d( new Data ) 46 : d( new Data )
47{ 47{
48} 48}
49 49
50Mutex::~Mutex() 50Mutex::~Mutex()
51{ 51{
52 delete d; 52 delete d;
53} 53}
54 54
55void Mutex::lock() 55void Mutex::lock()
56{ 56{
57 pthread_mutex_lock( &d->mutex ); 57 pthread_mutex_lock( &d->mutex );
58} 58}
59 59
60void Mutex::unlock() 60void Mutex::unlock()
61{ 61{
62 pthread_mutex_unlock( &d->mutex ); 62 pthread_mutex_unlock( &d->mutex );
63} 63}
64 64
65bool Mutex::tryLock() 65bool Mutex::tryLock()
66{ 66{
67 return pthread_mutex_trylock( &d->mutex ) == 0; 67 return pthread_mutex_trylock( &d->mutex ) == 0;
68} 68}
69 69
70bool Mutex::isLocked() 70bool Mutex::isLocked()
71{ 71{
72 if ( !tryLock() ) 72 if ( !tryLock() )
73 return true; 73 return true;
74 74
75 unlock(); 75 unlock();
76 return false; 76 return false;
77} 77}
78 78
79struct WaitCondition::Data 79struct WaitCondition::Data
80{ 80{
81 Data() 81 Data()
82 { 82 {
83 int result = pthread_cond_init( &waitCondition, 0 ); 83 int result = pthread_cond_init( &waitCondition, 0 );
84 assert( result == 0 ); 84 assert( result == 0 );
85 } 85 }
86 ~Data() 86 ~Data()
87 { 87 {
88 pthread_cond_destroy( &waitCondition ); 88 pthread_cond_destroy( &waitCondition );
89 } 89 }
90 90
91 pthread_cond_t waitCondition; 91 pthread_cond_t waitCondition;
92}; 92};
93 93
94WaitCondition::WaitCondition() 94WaitCondition::WaitCondition()
95 : d( new Data ) 95 : d( new Data )
96{ 96{
97} 97}
98 98
99WaitCondition::~WaitCondition() 99WaitCondition::~WaitCondition()
100{ 100{
101 delete d; 101 delete d;
102} 102}
103 103
104bool WaitCondition::wait() 104bool WaitCondition::wait()
105{ 105{
106 Mutex m; 106 Mutex m;
107 m.lock(); 107 m.lock();
108 return wait( m ); 108 return wait( m );
109} 109}
110 110
111bool WaitCondition::wait( Mutex &mutex ) 111bool WaitCondition::wait( Mutex &mutex )
112{ 112{
113 return pthread_cond_wait( &d->waitCondition, &mutex.d->mutex ); 113 return pthread_cond_wait( &d->waitCondition, &mutex.d->mutex );
114} 114}
115 115
116void WaitCondition::wakeOne() 116void WaitCondition::wakeOne()
117{ 117{
118 pthread_cond_signal( &d->waitCondition ); 118 pthread_cond_signal( &d->waitCondition );
119} 119}
120 120
121void WaitCondition::wakeAll() 121void WaitCondition::wakeAll()
122{ 122{
123 pthread_cond_broadcast( &d->waitCondition ); 123 pthread_cond_broadcast( &d->waitCondition );
124} 124}
125 125
126struct Thread::Data 126struct Thread::Data
127{ 127{
128 Data() : isRunning( false ) 128 Data() : isRunning( false )
129 {} 129 {}
130 130
131 pthread_t self; 131 pthread_t self;
132 Mutex guard; 132 Mutex guard;
133 bool isRunning; 133 bool isRunning;
134 134
135 WaitCondition finishCondition; 135 WaitCondition finishCondition;
136
137 Thread *thr;
138
139 void run() { thr->run(); }
136}; 140};
137 141
138extern "C" 142extern "C"
139{ 143{
140 144
141static void terminate_thread( void *arg ) 145static void terminate_thread( void *arg )
142{ 146{
143 Thread::Data *data = ( Thread::Data* )arg; 147 Thread::Data *data = ( Thread::Data* )arg;
144 148
145 assert( data ); 149 assert( data );
146 150
147 AutoLock locker( data->guard ); 151 AutoLock locker( data->guard );
148 data->isRunning = false; 152 data->isRunning = false;
149 data->finishCondition.wakeAll(); 153 data->finishCondition.wakeAll();
150} 154}
151 155
152void *_threadutil_start_thread( void *arg ) 156static void *start_thread( void *arg )
153{ 157{
154 Thread *thr = ( Thread* )arg; 158 Thread::Data *data = ( Thread::Data* )arg;
155 159
156 pthread_cleanup_push( terminate_thread, thr->d ); 160 pthread_cleanup_push( terminate_thread, data );
157 161
158 thr->d->isRunning = true; 162 data->isRunning = true;
159 thr->run(); 163 data->run();
160 164
161 pthread_cleanup_pop( true ); 165 pthread_cleanup_pop( true );
162 166
163 Thread::exit(); 167 Thread::exit();
164 return 0; // never reached 168 return 0; // never reached
165} 169}
166 170
167} 171}
168 172
169Thread::Thread() 173Thread::Thread()
170 : d( new Data ) 174 : d( new Data )
171{ 175{
176 d->thr = this;
172} 177}
173 178
174Thread::~Thread() 179Thread::~Thread()
175{ 180{
176 assert( d->isRunning == false ); 181 assert( d->isRunning == false );
177 delete d; 182 delete d;
178} 183}
179 184
180void Thread::start() 185void Thread::start()
181{ 186{
182 AutoLock lock( d->guard ); 187 AutoLock lock( d->guard );
183 188
184 if ( d->isRunning ) { 189 if ( d->isRunning ) {
185 qDebug( "ThreadUtil::Thread::start() called for running thread." ); 190 qDebug( "ThreadUtil::Thread::start() called for running thread." );
186 return; 191 return;
187 } 192 }
188 193
189 pthread_attr_t attributes; 194 pthread_attr_t attributes;
190 pthread_attr_init( &attributes ); 195 pthread_attr_init( &attributes );
191 pthread_attr_setscope( &attributes, PTHREAD_SCOPE_SYSTEM ); 196 pthread_attr_setscope( &attributes, PTHREAD_SCOPE_SYSTEM );
192 int err = pthread_create( &d->self, &attributes, _threadutil_start_thread, ( void* )this ); 197 int err = pthread_create( &d->self, &attributes, start_thread, ( void* )d );
193 if ( err != 0 ) { 198 if ( err != 0 ) {
194 qDebug( "ThreadUtil::Thread::start() : can't create thread: %s", strerror( err ) ); 199 qDebug( "ThreadUtil::Thread::start() : can't create thread: %s", strerror( err ) );
195 pthread_attr_destroy( &attributes ); 200 pthread_attr_destroy( &attributes );
196 return; 201 return;
197 } 202 }
198 pthread_attr_destroy( &attributes ); 203 pthread_attr_destroy( &attributes );
199} 204}
200 205
201void Thread::terminate() 206void Thread::terminate()
202{ 207{
203 AutoLock lock( d->guard ); 208 AutoLock lock( d->guard );
204 if ( !d->isRunning ) 209 if ( !d->isRunning )
205 return; 210 return;
206 211
207 pthread_cancel( d->self ); 212 pthread_cancel( d->self );
208} 213}
209 214
210bool Thread::wait() 215bool Thread::wait()
211{ 216{
212 AutoLock lock( d->guard ); 217 AutoLock lock( d->guard );
213 if ( !d->isRunning ) 218 if ( !d->isRunning )
214 return true; 219 return true;
215 220
216 return d->finishCondition.wait( d->guard ); 221 return d->finishCondition.wait( d->guard );
217} 222}
218 223
219bool Thread::isRunning() const 224bool Thread::isRunning() const
220{ 225{
221 AutoLock lock( d->guard ); 226 AutoLock lock( d->guard );
222 return d->isRunning; 227 return d->isRunning;
223} 228}
224 229
225void Thread::exit() 230void Thread::exit()
226{ 231{
227 pthread_exit( 0 ); 232 pthread_exit( 0 );
228} 233}
229 234
230OnewayNotifier::OnewayNotifier() 235OnewayNotifier::OnewayNotifier()
231{ 236{
232 int fds[ 2 ]; 237 int fds[ 2 ];
233 pipe( fds ); 238 pipe( fds );
234 m_readFd = fds[ 0 ]; 239 m_readFd = fds[ 0 ];
235 m_writeFd = fds[ 1 ]; 240 m_writeFd = fds[ 1 ];
236 241
237 m_notifier = new QSocketNotifier( m_readFd, QSocketNotifier::Read ); 242 m_notifier = new QSocketNotifier( m_readFd, QSocketNotifier::Read );
238 connect( m_notifier, SIGNAL( activated( int ) ), 243 connect( m_notifier, SIGNAL( activated( int ) ),
239 this, SLOT( wakeUp() ) ); 244 this, SLOT( wakeUp() ) );
240} 245}
241 246
242OnewayNotifier::~OnewayNotifier() 247OnewayNotifier::~OnewayNotifier()
243{ 248{
244 delete m_notifier; 249 delete m_notifier;
245 250
246 ::close( m_readFd ); 251 ::close( m_readFd );
247 ::close( m_writeFd ); 252 ::close( m_writeFd );
248} 253}
249 254
250void OnewayNotifier::notify() 255void OnewayNotifier::notify()
251{ 256{
252 const char c = 42; 257 const char c = 42;
253 ::write( m_writeFd, &c, 1 ); 258 ::write( m_writeFd, &c, 1 );
254} 259}
255 260
256void OnewayNotifier::wakeUp() 261void OnewayNotifier::wakeUp()
257{ 262{
258 char c = 0; 263 char c = 0;
259 264
260 if ( ::read( m_readFd, &c, 1 ) != 1 ) 265 if ( ::read( m_readFd, &c, 1 ) != 1 )
261 return; 266 return;
262 267
263 emit awake(); 268 emit awake();
264} 269}
265 270
266ChannelMessage::ChannelMessage( int type ) 271ChannelMessage::ChannelMessage( int type )
267 : m_type( type ), m_isCall( false ), m_replied( false ), 272 : m_type( type ), m_isCall( false ), m_replied( false ),
268 m_inEventHandler( false ) 273 m_inEventHandler( false )
269{ 274{
270} 275}
271 276
272ChannelMessage::~ChannelMessage() 277ChannelMessage::~ChannelMessage()
273{ 278{
274 if ( m_guard.isLocked() ) 279 if ( m_guard.isLocked() )
275 m_guard.unlock(); 280 m_guard.unlock();
276} 281}
277 282
278void ChannelMessage::reply() 283void ChannelMessage::reply()
279{ 284{
280 if ( !m_isCall ) 285 if ( !m_isCall )
281 { 286 {
282 qDebug( "ChannelMessage::reply() - can't reply oneway message!" ); 287 qDebug( "ChannelMessage::reply() - can't reply oneway message!" );
283 return; 288 return;
284 } 289 }
285 290
286 if ( m_inEventHandler ) 291 if ( m_inEventHandler )
287 { 292 {
288 m_replied = true; 293 m_replied = true;
289 return; 294 return;
290 } 295 }
291 296
292 m_condition.wakeOne(); 297 m_condition.wakeOne();
293 m_guard.unlock(); 298 m_guard.unlock();
294} 299}
295 300
296struct Channel::Private 301struct Channel::Private
297{ 302{
298 Private() 303 Private()
299 { 304 {
300 ownerThread = pthread_self(); 305 ownerThread = pthread_self();
301 } 306 }
302 307
303 pthread_t ownerThread; 308 pthread_t ownerThread;
304}; 309};
305 310
306Channel::Channel( QObject *parent, const char *name ) 311Channel::Channel( QObject *parent, const char *name )
307 : QObject( parent, name ), d( new Private ) 312 : QObject( parent, name ), d( new Private )
308{ 313{
309 connect( &m_notifier, SIGNAL( awake() ), 314 connect( &m_notifier, SIGNAL( awake() ),
310 this, SLOT( deliver() ) ); 315 this, SLOT( deliver() ) );
311} 316}
312 317
313Channel::~Channel() 318Channel::~Channel()
314{ 319{
315 delete d; 320 delete d;
316} 321}
317 322
318void Channel::send( ChannelMessage *message, SendType type ) 323void Channel::send( ChannelMessage *message, SendType type )
319{ 324{
320 if ( type == WaitForReply ) 325 if ( type == WaitForReply )
321 { 326 {
322 message->m_guard.lock(); 327 message->m_guard.lock();
323 message->m_isCall = true; 328 message->m_isCall = true;
324 } 329 }
325 330
326 m_pendingMessagesGuard.lock(); 331 m_pendingMessagesGuard.lock();
327 m_pendingMessages << MsgEnvelope( type, message ); 332 m_pendingMessages << MsgEnvelope( type, message );
328 m_pendingMessagesGuard.unlock(); 333 m_pendingMessagesGuard.unlock();
329 334
330 if ( d->ownerThread == pthread_self() ) { 335 if ( d->ownerThread == pthread_self() ) {
331 assert( type != WaitForReply ); 336 assert( type != WaitForReply );
332 337
333 deliver(); 338 deliver();
334 } 339 }
335 else 340 else
336 m_notifier.notify(); 341 m_notifier.notify();
337 //QThread::postEvent( this, new QCustomEvent( QEvent::User, envelope ) ); 342 //QThread::postEvent( this, new QCustomEvent( QEvent::User, envelope ) );
338 343
339 if ( type == WaitForReply ) 344 if ( type == WaitForReply )
340 { 345 {
341 message->m_condition.wait( message->m_guard ); 346 message->m_condition.wait( message->m_guard );
342 message->m_guard.unlock(); 347 message->m_guard.unlock();
343 } 348 }
344} 349}
345 350
346void Channel::deliver() 351void Channel::deliver()
347{ 352{
348 AutoLock lock( m_pendingMessagesGuard ); 353 AutoLock lock( m_pendingMessagesGuard );
349 354
350 while ( !m_pendingMessages.isEmpty() ) { 355 while ( !m_pendingMessages.isEmpty() ) {
351 MsgEnvelope envelope = m_pendingMessages.first(); 356 MsgEnvelope envelope = m_pendingMessages.first();
352 357
353 m_pendingMessages.remove( m_pendingMessages.begin() ); 358 m_pendingMessages.remove( m_pendingMessages.begin() );
354 359
355 m_pendingMessagesGuard.unlock(); 360 m_pendingMessagesGuard.unlock();
356 deliverOne( envelope ); 361 deliverOne( envelope );
357 m_pendingMessagesGuard.lock(); 362 m_pendingMessagesGuard.lock();
358 } 363 }
359} 364}
360 365
361void Channel::deliverOne( const MsgEnvelope &envelope ) 366void Channel::deliverOne( const MsgEnvelope &envelope )
362{ 367{
363 ChannelMessage *msg = envelope.msg; 368 ChannelMessage *msg = envelope.msg;
364 369
365 assert( msg ); 370 assert( msg );
366 371
367 if ( envelope.type == WaitForReply ) 372 if ( envelope.type == WaitForReply )
368 { 373 {
369 msg->m_guard.lock(); 374 msg->m_guard.lock();
370 msg->m_inEventHandler = true; 375 msg->m_inEventHandler = true;
371 } 376 }
372 377
373 receiveMessage( msg, envelope.type ); 378 receiveMessage( msg, envelope.type );
374 379
375 if ( envelope.type == WaitForReply ) 380 if ( envelope.type == WaitForReply )
376 { 381 {
377 msg->m_inEventHandler = false; 382 msg->m_inEventHandler = false;
378 if ( msg->m_replied ) 383 if ( msg->m_replied )
379 { 384 {
380 msg->m_condition.wakeOne(); 385 msg->m_condition.wakeOne();
381 // this is a bit tricky. we unlock only when we reply. 386 // this is a bit tricky. we unlock only when we reply.
382 // reply() does an unlock as well. 387 // reply() does an unlock as well.
383 msg->m_guard.unlock(); 388 msg->m_guard.unlock();
384 } 389 }
385 } 390 }
386} 391}
387 392
388/* vim: et sw=4 ts=4 393/* vim: et sw=4 ts=4
389 */ 394 */
diff --git a/noncore/multimedia/opieplayer2/threadutil.h b/noncore/multimedia/opieplayer2/threadutil.h
index 21ae6b2..2fd0c68 100644
--- a/noncore/multimedia/opieplayer2/threadutil.h
+++ b/noncore/multimedia/opieplayer2/threadutil.h
@@ -1,205 +1,199 @@
1/* This file is part of the KDE project 1/* This file is part of the KDE project
2 Copyright (C) 2002 Simon Hausmann <hausmann@kde.org> 2 Copyright (C) 2002 Simon Hausmann <hausmann@kde.org>
3 3
4 This library is free software; you can redistribute it and/or 4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public 5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either 6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version. 7 version 2 of the License, or (at your option) any later version.
8 8
9 This library is distributed in the hope that it will be useful, 9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of 10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details. 12 Library General Public License for more details.
13 13
14 You should have received a copy of the GNU Library General Public License 14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to 15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 16 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA. 17 Boston, MA 02111-1307, USA.
18*/ 18*/
19 19
20#ifndef THREADUTIL_H 20#ifndef THREADUTIL_H
21#define THREADUTIL_H 21#define THREADUTIL_H
22 22
23#include <qvaluelist.h> 23#include <qvaluelist.h>
24#include <qobject.h> 24#include <qobject.h>
25#include <qguardedptr.h> 25#include <qguardedptr.h>
26 26
27class QSocketNotifier; 27class QSocketNotifier;
28 28
29extern "C"
30{
31 void *_threadutil_start_thread( void* );
32}
33
34namespace ThreadUtil 29namespace ThreadUtil
35{ 30{
36 31
37 class Mutex 32 class Mutex
38 { 33 {
39 friend class WaitCondition; 34 friend class WaitCondition;
40 public: 35 public:
41 Mutex(); 36 Mutex();
42 ~Mutex(); 37 ~Mutex();
43 38
44 void lock(); 39 void lock();
45 void unlock(); 40 void unlock();
46 bool tryLock(); 41 bool tryLock();
47 bool isLocked(); 42 bool isLocked();
48 43
49 private: 44 private:
50 struct Data; 45 struct Data;
51 Data *d; 46 Data *d;
52 47
53 Mutex( const Mutex & ); 48 Mutex( const Mutex & );
54 Mutex &operator=( const Mutex & ); 49 Mutex &operator=( const Mutex & );
55 }; 50 };
56 51
57 class AutoLock 52 class AutoLock
58 { 53 {
59 public: 54 public:
60 AutoLock( Mutex &mutex ) : m_mutex( mutex ) { m_mutex.lock(); } 55 AutoLock( Mutex &mutex ) : m_mutex( mutex ) { m_mutex.lock(); }
61 ~AutoLock() { m_mutex.unlock(); } 56 ~AutoLock() { m_mutex.unlock(); }
62 57
63 Mutex *operator &() const { return &m_mutex; } 58 Mutex *operator &() const { return &m_mutex; }
64 59
65 private: 60 private:
66 Mutex &m_mutex; 61 Mutex &m_mutex;
67 }; 62 };
68 63
69 class WaitCondition 64 class WaitCondition
70 { 65 {
71 public: 66 public:
72 WaitCondition(); 67 WaitCondition();
73 ~WaitCondition(); 68 ~WaitCondition();
74 69
75 bool wait(); 70 bool wait();
76 bool wait( Mutex &mutex ); 71 bool wait( Mutex &mutex );
77 72
78 void wakeOne(); 73 void wakeOne();
79 void wakeAll(); 74 void wakeAll();
80 75
81 private: 76 private:
82 struct Data; 77 struct Data;
83 Data *d; 78 Data *d;
84 79
85 WaitCondition( const WaitCondition & ); 80 WaitCondition( const WaitCondition & );
86 WaitCondition &operator=( const WaitCondition & ); 81 WaitCondition &operator=( const WaitCondition & );
87 }; 82 };
88 83
89 class Thread 84 class Thread
90 { 85 {
91 friend void *::_threadutil_start_thread( void* );
92 public: 86 public:
93 struct Data; 87 struct Data;
94 88
95 Thread(); 89 Thread();
96 virtual ~Thread(); 90 virtual ~Thread();
97 91
98 void start(); 92 void start();
99 void terminate(); 93 void terminate();
100 94
101 bool wait(); 95 bool wait();
102 96
103 bool isRunning() const; 97 bool isRunning() const;
104 98
105 static void exit(); 99 static void exit();
106 protected: 100 protected:
107 virtual void run() = 0; 101 virtual void run() = 0;
108 102
109 private: 103 private:
110 Data *d; 104 Data *d;
111 }; 105 };
112 106
113 class OnewayNotifier : public QObject 107 class OnewayNotifier : public QObject
114 { 108 {
115 Q_OBJECT 109 Q_OBJECT
116 public: 110 public:
117 OnewayNotifier(); 111 OnewayNotifier();
118 ~OnewayNotifier(); 112 ~OnewayNotifier();
119 113
120 void notify(); 114 void notify();
121 115
122 signals: 116 signals:
123 void awake(); 117 void awake();
124 118
125 private slots: 119 private slots:
126 void wakeUp(); 120 void wakeUp();
127 121
128 private: 122 private:
129 int m_readFd; 123 int m_readFd;
130 int m_writeFd; 124 int m_writeFd;
131 QSocketNotifier *m_notifier; 125 QSocketNotifier *m_notifier;
132 }; 126 };
133 127
134 128
135 class Channel; 129 class Channel;
136 130
137 class ChannelMessage 131 class ChannelMessage
138 { 132 {
139 friend class Channel; 133 friend class Channel;
140 public: 134 public:
141 ChannelMessage( int type = -1 ); 135 ChannelMessage( int type = -1 );
142 virtual ~ChannelMessage(); 136 virtual ~ChannelMessage();
143 137
144 int type() const { return m_type; } 138 int type() const { return m_type; }
145 139
146 void reply(); 140 void reply();
147 141
148 private: 142 private:
149 ChannelMessage( const ChannelMessage & ); 143 ChannelMessage( const ChannelMessage & );
150 ChannelMessage &operator=( const ChannelMessage ); 144 ChannelMessage &operator=( const ChannelMessage );
151 145
152 int m_type; 146 int m_type;
153 bool m_isCall : 1; 147 bool m_isCall : 1;
154 bool m_replied : 1; 148 bool m_replied : 1;
155 bool m_inEventHandler : 1; 149 bool m_inEventHandler : 1;
156 Mutex m_guard; 150 Mutex m_guard;
157 WaitCondition m_condition; 151 WaitCondition m_condition;
158 QGuardedPtr<Channel> m_channel; 152 QGuardedPtr<Channel> m_channel;
159 }; 153 };
160 154
161 class Channel : public QObject 155 class Channel : public QObject
162 { 156 {
163 Q_OBJECT 157 Q_OBJECT
164 public: 158 public:
165 enum SendType { OneWay, WaitForReply }; 159 enum SendType { OneWay, WaitForReply };
166 Channel( QObject *parent = 0, const char *name = 0 ); 160 Channel( QObject *parent = 0, const char *name = 0 );
167 virtual ~Channel(); 161 virtual ~Channel();
168 162
169 void send( ChannelMessage *message, SendType type ); 163 void send( ChannelMessage *message, SendType type );
170 164
171 protected: 165 protected:
172 virtual void receiveMessage( ChannelMessage *message, SendType type ) = 0; 166 virtual void receiveMessage( ChannelMessage *message, SendType type ) = 0;
173 167
174 private slots: 168 private slots:
175 void deliver(); 169 void deliver();
176 170
177 private: 171 private:
178 OnewayNotifier m_notifier; 172 OnewayNotifier m_notifier;
179 173
180 struct MsgEnvelope 174 struct MsgEnvelope
181 { 175 {
182 MsgEnvelope() : type( OneWay ), msg( 0 ) {} 176 MsgEnvelope() : type( OneWay ), msg( 0 ) {}
183 MsgEnvelope( SendType _type , ChannelMessage *_msg ) 177 MsgEnvelope( SendType _type , ChannelMessage *_msg )
184 : type( _type ), msg( _msg ) {} 178 : type( _type ), msg( _msg ) {}
185 179
186 SendType type; 180 SendType type;
187 ChannelMessage *msg; 181 ChannelMessage *msg;
188 }; 182 };
189 183
190 void deliverOne( const MsgEnvelope &envelope ); 184 void deliverOne( const MsgEnvelope &envelope );
191 185
192 typedef QValueList<MsgEnvelope> MsgEnvelopeList; 186 typedef QValueList<MsgEnvelope> MsgEnvelopeList;
193 187
194 MsgEnvelopeList m_pendingMessages; 188 MsgEnvelopeList m_pendingMessages;
195 Mutex m_pendingMessagesGuard; 189 Mutex m_pendingMessagesGuard;
196 190
197 struct Private; 191 struct Private;
198 Private *d; 192 Private *d;
199 }; 193 };
200 194
201} 195}
202 196
203#endif // THREADUTIL_H 197#endif // THREADUTIL_H
204/* vim: et sw=4 ts=4 198/* vim: et sw=4 ts=4
205 */ 199 */