summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/multimedia/opieplayer2/threadutil.cpp6
-rw-r--r--noncore/multimedia/opieplayer2/threadutil.h2
2 files changed, 8 insertions, 0 deletions
diff --git a/noncore/multimedia/opieplayer2/threadutil.cpp b/noncore/multimedia/opieplayer2/threadutil.cpp
index 5687f42..a5cc92d 100644
--- a/noncore/multimedia/opieplayer2/threadutil.cpp
+++ b/noncore/multimedia/opieplayer2/threadutil.cpp
@@ -1,383 +1,389 @@
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}; 136};
137 137
138extern "C" 138extern "C"
139{ 139{
140 140
141void _threadutil_terminate_thread( void *arg ) 141void _threadutil_terminate_thread( void *arg )
142{ 142{
143 Thread *thr = ( Thread* )arg; 143 Thread *thr = ( Thread* )arg;
144 144
145 assert( thr ); 145 assert( thr );
146 146
147 AutoLock locker( thr->d->guard ); 147 AutoLock locker( thr->d->guard );
148 thr->d->isRunning = false; 148 thr->d->isRunning = false;
149 thr->d->finishCondition.wakeAll(); 149 thr->d->finishCondition.wakeAll();
150} 150}
151 151
152void *_threadutil_start_thread( void *arg ) 152void *_threadutil_start_thread( void *arg )
153{ 153{
154 Thread *thr = ( Thread* )arg; 154 Thread *thr = ( Thread* )arg;
155 155
156 pthread_cleanup_push( _threadutil_terminate_thread, thr ); 156 pthread_cleanup_push( _threadutil_terminate_thread, thr );
157 157
158 thr->d->isRunning = true; 158 thr->d->isRunning = true;
159 thr->run(); 159 thr->run();
160 160
161 pthread_cleanup_pop( true ); 161 pthread_cleanup_pop( true );
162 162
163 Thread::exit(); 163 Thread::exit();
164 return 0; // never reached 164 return 0; // never reached
165} 165}
166 166
167} 167}
168 168
169Thread::Thread() 169Thread::Thread()
170 : d( new Data ) 170 : d( new Data )
171{ 171{
172} 172}
173 173
174Thread::~Thread() 174Thread::~Thread()
175{ 175{
176 assert( d->isRunning == false ); 176 assert( d->isRunning == false );
177 delete d; 177 delete d;
178} 178}
179 179
180void Thread::start() 180void Thread::start()
181{ 181{
182 AutoLock lock( d->guard ); 182 AutoLock lock( d->guard );
183 183
184 if ( d->isRunning ) { 184 if ( d->isRunning ) {
185 qDebug( "ThreadUtil::Thread::start() called for running thread." ); 185 qDebug( "ThreadUtil::Thread::start() called for running thread." );
186 return; 186 return;
187 } 187 }
188 188
189 pthread_attr_t attributes; 189 pthread_attr_t attributes;
190 pthread_attr_init( &attributes ); 190 pthread_attr_init( &attributes );
191 pthread_attr_setscope( &attributes, PTHREAD_SCOPE_SYSTEM ); 191 pthread_attr_setscope( &attributes, PTHREAD_SCOPE_SYSTEM );
192 int err = pthread_create( &d->self, &attributes, _threadutil_start_thread, ( void* )this ); 192 int err = pthread_create( &d->self, &attributes, _threadutil_start_thread, ( void* )this );
193 if ( err != 0 ) { 193 if ( err != 0 ) {
194 qDebug( "ThreadUtil::Thread::start() : can't create thread: %s", strerror( err ) ); 194 qDebug( "ThreadUtil::Thread::start() : can't create thread: %s", strerror( err ) );
195 pthread_attr_destroy( &attributes ); 195 pthread_attr_destroy( &attributes );
196 return; 196 return;
197 } 197 }
198 pthread_attr_destroy( &attributes ); 198 pthread_attr_destroy( &attributes );
199} 199}
200 200
201void Thread::terminate() 201void Thread::terminate()
202{ 202{
203 AutoLock lock( d->guard ); 203 AutoLock lock( d->guard );
204 if ( !d->isRunning ) 204 if ( !d->isRunning )
205 return; 205 return;
206 206
207 pthread_cancel( d->self ); 207 pthread_cancel( d->self );
208} 208}
209 209
210bool Thread::wait() 210bool Thread::wait()
211{ 211{
212 AutoLock lock( d->guard ); 212 AutoLock lock( d->guard );
213 if ( !d->isRunning ) 213 if ( !d->isRunning )
214 return true; 214 return true;
215 215
216 return d->finishCondition.wait( d->guard ); 216 return d->finishCondition.wait( d->guard );
217} 217}
218 218
219bool Thread::isRunning() const
220{
221 AutoLock lock( d->guard );
222 return d->isRunning;
223}
224
219void Thread::exit() 225void Thread::exit()
220{ 226{
221 pthread_exit( 0 ); 227 pthread_exit( 0 );
222} 228}
223 229
224OnewayNotifier::OnewayNotifier() 230OnewayNotifier::OnewayNotifier()
225{ 231{
226 int fds[ 2 ]; 232 int fds[ 2 ];
227 pipe( fds ); 233 pipe( fds );
228 m_readFd = fds[ 0 ]; 234 m_readFd = fds[ 0 ];
229 m_writeFd = fds[ 1 ]; 235 m_writeFd = fds[ 1 ];
230 236
231 m_notifier = new QSocketNotifier( m_readFd, QSocketNotifier::Read ); 237 m_notifier = new QSocketNotifier( m_readFd, QSocketNotifier::Read );
232 connect( m_notifier, SIGNAL( activated( int ) ), 238 connect( m_notifier, SIGNAL( activated( int ) ),
233 this, SLOT( wakeUp() ) ); 239 this, SLOT( wakeUp() ) );
234} 240}
235 241
236OnewayNotifier::~OnewayNotifier() 242OnewayNotifier::~OnewayNotifier()
237{ 243{
238 delete m_notifier; 244 delete m_notifier;
239 245
240 ::close( m_readFd ); 246 ::close( m_readFd );
241 ::close( m_writeFd ); 247 ::close( m_writeFd );
242} 248}
243 249
244void OnewayNotifier::notify() 250void OnewayNotifier::notify()
245{ 251{
246 const char c = 42; 252 const char c = 42;
247 ::write( m_writeFd, &c, 1 ); 253 ::write( m_writeFd, &c, 1 );
248} 254}
249 255
250void OnewayNotifier::wakeUp() 256void OnewayNotifier::wakeUp()
251{ 257{
252 char c = 0; 258 char c = 0;
253 259
254 if ( ::read( m_readFd, &c, 1 ) != 1 ) 260 if ( ::read( m_readFd, &c, 1 ) != 1 )
255 return; 261 return;
256 262
257 emit awake(); 263 emit awake();
258} 264}
259 265
260ChannelMessage::ChannelMessage( int type ) 266ChannelMessage::ChannelMessage( int type )
261 : m_type( type ), m_isCall( false ), m_replied( false ), 267 : m_type( type ), m_isCall( false ), m_replied( false ),
262 m_inEventHandler( false ) 268 m_inEventHandler( false )
263{ 269{
264} 270}
265 271
266ChannelMessage::~ChannelMessage() 272ChannelMessage::~ChannelMessage()
267{ 273{
268 if ( m_guard.isLocked() ) 274 if ( m_guard.isLocked() )
269 m_guard.unlock(); 275 m_guard.unlock();
270} 276}
271 277
272void ChannelMessage::reply() 278void ChannelMessage::reply()
273{ 279{
274 if ( !m_isCall ) 280 if ( !m_isCall )
275 { 281 {
276 qDebug( "ChannelMessage::reply() - can't reply oneway message!" ); 282 qDebug( "ChannelMessage::reply() - can't reply oneway message!" );
277 return; 283 return;
278 } 284 }
279 285
280 if ( m_inEventHandler ) 286 if ( m_inEventHandler )
281 { 287 {
282 m_replied = true; 288 m_replied = true;
283 return; 289 return;
284 } 290 }
285 291
286 m_condition.wakeOne(); 292 m_condition.wakeOne();
287 m_guard.unlock(); 293 m_guard.unlock();
288} 294}
289 295
290struct Channel::Private 296struct Channel::Private
291{ 297{
292 Private() 298 Private()
293 { 299 {
294 ownerThread = pthread_self(); 300 ownerThread = pthread_self();
295 } 301 }
296 302
297 pthread_t ownerThread; 303 pthread_t ownerThread;
298}; 304};
299 305
300Channel::Channel( QObject *parent, const char *name ) 306Channel::Channel( QObject *parent, const char *name )
301 : QObject( parent, name ), d( new Private ) 307 : QObject( parent, name ), d( new Private )
302{ 308{
303 connect( &m_notifier, SIGNAL( awake() ), 309 connect( &m_notifier, SIGNAL( awake() ),
304 this, SLOT( deliver() ) ); 310 this, SLOT( deliver() ) );
305} 311}
306 312
307Channel::~Channel() 313Channel::~Channel()
308{ 314{
309 delete d; 315 delete d;
310} 316}
311 317
312void Channel::send( ChannelMessage *message, SendType type ) 318void Channel::send( ChannelMessage *message, SendType type )
313{ 319{
314 if ( type == WaitForReply ) 320 if ( type == WaitForReply )
315 { 321 {
316 message->m_guard.lock(); 322 message->m_guard.lock();
317 message->m_isCall = true; 323 message->m_isCall = true;
318 } 324 }
319 325
320 m_pendingMessagesGuard.lock(); 326 m_pendingMessagesGuard.lock();
321 m_pendingMessages << MsgEnvelope( type, message ); 327 m_pendingMessages << MsgEnvelope( type, message );
322 m_pendingMessagesGuard.unlock(); 328 m_pendingMessagesGuard.unlock();
323 329
324 if ( d->ownerThread == pthread_self() ) { 330 if ( d->ownerThread == pthread_self() ) {
325 assert( type != WaitForReply ); 331 assert( type != WaitForReply );
326 332
327 deliver(); 333 deliver();
328 } 334 }
329 else 335 else
330 m_notifier.notify(); 336 m_notifier.notify();
331 //QThread::postEvent( this, new QCustomEvent( QEvent::User, envelope ) ); 337 //QThread::postEvent( this, new QCustomEvent( QEvent::User, envelope ) );
332 338
333 if ( type == WaitForReply ) 339 if ( type == WaitForReply )
334 { 340 {
335 message->m_condition.wait( message->m_guard ); 341 message->m_condition.wait( message->m_guard );
336 message->m_guard.unlock(); 342 message->m_guard.unlock();
337 } 343 }
338} 344}
339 345
340void Channel::deliver() 346void Channel::deliver()
341{ 347{
342 AutoLock lock( m_pendingMessagesGuard ); 348 AutoLock lock( m_pendingMessagesGuard );
343 349
344 while ( !m_pendingMessages.isEmpty() ) { 350 while ( !m_pendingMessages.isEmpty() ) {
345 MsgEnvelope envelope = m_pendingMessages.first(); 351 MsgEnvelope envelope = m_pendingMessages.first();
346 352
347 m_pendingMessages.remove( m_pendingMessages.begin() ); 353 m_pendingMessages.remove( m_pendingMessages.begin() );
348 354
349 m_pendingMessagesGuard.unlock(); 355 m_pendingMessagesGuard.unlock();
350 deliverOne( envelope ); 356 deliverOne( envelope );
351 m_pendingMessagesGuard.lock(); 357 m_pendingMessagesGuard.lock();
352 } 358 }
353} 359}
354 360
355void Channel::deliverOne( const MsgEnvelope &envelope ) 361void Channel::deliverOne( const MsgEnvelope &envelope )
356{ 362{
357 ChannelMessage *msg = envelope.msg; 363 ChannelMessage *msg = envelope.msg;
358 364
359 assert( msg ); 365 assert( msg );
360 366
361 if ( envelope.type == WaitForReply ) 367 if ( envelope.type == WaitForReply )
362 { 368 {
363 msg->m_guard.lock(); 369 msg->m_guard.lock();
364 msg->m_inEventHandler = true; 370 msg->m_inEventHandler = true;
365 } 371 }
366 372
367 receiveMessage( msg, envelope.type ); 373 receiveMessage( msg, envelope.type );
368 374
369 if ( envelope.type == WaitForReply ) 375 if ( envelope.type == WaitForReply )
370 { 376 {
371 msg->m_inEventHandler = false; 377 msg->m_inEventHandler = false;
372 if ( msg->m_replied ) 378 if ( msg->m_replied )
373 { 379 {
374 msg->m_condition.wakeOne(); 380 msg->m_condition.wakeOne();
375 // this is a bit tricky. we unlock only when we reply. 381 // this is a bit tricky. we unlock only when we reply.
376 // reply() does an unlock as well. 382 // reply() does an unlock as well.
377 msg->m_guard.unlock(); 383 msg->m_guard.unlock();
378 } 384 }
379 } 385 }
380} 386}
381 387
382/* vim: et sw=4 ts=4 388/* vim: et sw=4 ts=4
383 */ 389 */
diff --git a/noncore/multimedia/opieplayer2/threadutil.h b/noncore/multimedia/opieplayer2/threadutil.h
index b537cc1..b67b61d 100644
--- a/noncore/multimedia/opieplayer2/threadutil.h
+++ b/noncore/multimedia/opieplayer2/threadutil.h
@@ -1,204 +1,206 @@
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" 29extern "C"
30{ 30{
31 void *_threadutil_start_thread( void* ); 31 void *_threadutil_start_thread( void* );
32 void _threadutil_terminate_thread( void* ); 32 void _threadutil_terminate_thread( void* );
33} 33}
34 34
35namespace ThreadUtil 35namespace ThreadUtil
36{ 36{
37 37
38 class Mutex 38 class Mutex
39 { 39 {
40 friend class WaitCondition; 40 friend class WaitCondition;
41 public: 41 public:
42 Mutex(); 42 Mutex();
43 ~Mutex(); 43 ~Mutex();
44 44
45 void lock(); 45 void lock();
46 void unlock(); 46 void unlock();
47 bool tryLock(); 47 bool tryLock();
48 bool isLocked(); 48 bool isLocked();
49 49
50 private: 50 private:
51 struct Data; 51 struct Data;
52 Data *d; 52 Data *d;
53 53
54 Mutex( const Mutex & ); 54 Mutex( const Mutex & );
55 Mutex &operator=( const Mutex & ); 55 Mutex &operator=( const Mutex & );
56 }; 56 };
57 57
58 class AutoLock 58 class AutoLock
59 { 59 {
60 public: 60 public:
61 AutoLock( Mutex &mutex ) : m_mutex( mutex ) { m_mutex.lock(); } 61 AutoLock( Mutex &mutex ) : m_mutex( mutex ) { m_mutex.lock(); }
62 ~AutoLock() { m_mutex.unlock(); } 62 ~AutoLock() { m_mutex.unlock(); }
63 63
64 Mutex *operator &() const { return &m_mutex; } 64 Mutex *operator &() const { return &m_mutex; }
65 65
66 private: 66 private:
67 Mutex &m_mutex; 67 Mutex &m_mutex;
68 }; 68 };
69 69
70 class WaitCondition 70 class WaitCondition
71 { 71 {
72 public: 72 public:
73 WaitCondition(); 73 WaitCondition();
74 ~WaitCondition(); 74 ~WaitCondition();
75 75
76 bool wait(); 76 bool wait();
77 bool wait( Mutex &mutex ); 77 bool wait( Mutex &mutex );
78 78
79 void wakeOne(); 79 void wakeOne();
80 void wakeAll(); 80 void wakeAll();
81 81
82 private: 82 private:
83 struct Data; 83 struct Data;
84 Data *d; 84 Data *d;
85 85
86 WaitCondition( const WaitCondition & ); 86 WaitCondition( const WaitCondition & );
87 WaitCondition &operator=( const WaitCondition & ); 87 WaitCondition &operator=( const WaitCondition & );
88 }; 88 };
89 89
90 class Thread 90 class Thread
91 { 91 {
92 friend void *::_threadutil_start_thread( void* ); 92 friend void *::_threadutil_start_thread( void* );
93 friend void ::_threadutil_terminate_thread( void* ); 93 friend void ::_threadutil_terminate_thread( void* );
94 public: 94 public:
95 Thread(); 95 Thread();
96 virtual ~Thread(); 96 virtual ~Thread();
97 97
98 void start(); 98 void start();
99 void terminate(); 99 void terminate();
100 100
101 bool wait(); 101 bool wait();
102 102
103 bool isRunning() const;
104
103 static void exit(); 105 static void exit();
104 protected: 106 protected:
105 virtual void run() = 0; 107 virtual void run() = 0;
106 108
107 private: 109 private:
108 struct Data; 110 struct Data;
109 Data *d; 111 Data *d;
110 }; 112 };
111 113
112 class OnewayNotifier : public QObject 114 class OnewayNotifier : public QObject
113 { 115 {
114 Q_OBJECT 116 Q_OBJECT
115 public: 117 public:
116 OnewayNotifier(); 118 OnewayNotifier();
117 ~OnewayNotifier(); 119 ~OnewayNotifier();
118 120
119 void notify(); 121 void notify();
120 122
121 signals: 123 signals:
122 void awake(); 124 void awake();
123 125
124 private slots: 126 private slots:
125 void wakeUp(); 127 void wakeUp();
126 128
127 private: 129 private:
128 int m_readFd; 130 int m_readFd;
129 int m_writeFd; 131 int m_writeFd;
130 QSocketNotifier *m_notifier; 132 QSocketNotifier *m_notifier;
131 }; 133 };
132 134
133 135
134 class Channel; 136 class Channel;
135 137
136 class ChannelMessage 138 class ChannelMessage
137 { 139 {
138 friend class Channel; 140 friend class Channel;
139 public: 141 public:
140 ChannelMessage( int type = -1 ); 142 ChannelMessage( int type = -1 );
141 virtual ~ChannelMessage(); 143 virtual ~ChannelMessage();
142 144
143 int type() const { return m_type; } 145 int type() const { return m_type; }
144 146
145 void reply(); 147 void reply();
146 148
147 private: 149 private:
148 ChannelMessage( const ChannelMessage & ); 150 ChannelMessage( const ChannelMessage & );
149 ChannelMessage &operator=( const ChannelMessage ); 151 ChannelMessage &operator=( const ChannelMessage );
150 152
151 int m_type; 153 int m_type;
152 bool m_isCall : 1; 154 bool m_isCall : 1;
153 bool m_replied : 1; 155 bool m_replied : 1;
154 bool m_inEventHandler : 1; 156 bool m_inEventHandler : 1;
155 Mutex m_guard; 157 Mutex m_guard;
156 WaitCondition m_condition; 158 WaitCondition m_condition;
157 QGuardedPtr<Channel> m_channel; 159 QGuardedPtr<Channel> m_channel;
158 }; 160 };
159 161
160 class Channel : public QObject 162 class Channel : public QObject
161 { 163 {
162 Q_OBJECT 164 Q_OBJECT
163 public: 165 public:
164 enum SendType { OneWay, WaitForReply }; 166 enum SendType { OneWay, WaitForReply };
165 Channel( QObject *parent = 0, const char *name = 0 ); 167 Channel( QObject *parent = 0, const char *name = 0 );
166 virtual ~Channel(); 168 virtual ~Channel();
167 169
168 void send( ChannelMessage *message, SendType type ); 170 void send( ChannelMessage *message, SendType type );
169 171
170 protected: 172 protected:
171 virtual void receiveMessage( ChannelMessage *message, SendType type ) = 0; 173 virtual void receiveMessage( ChannelMessage *message, SendType type ) = 0;
172 174
173 private slots: 175 private slots:
174 void deliver(); 176 void deliver();
175 177
176 private: 178 private:
177 OnewayNotifier m_notifier; 179 OnewayNotifier m_notifier;
178 180
179 struct MsgEnvelope 181 struct MsgEnvelope
180 { 182 {
181 MsgEnvelope() : type( OneWay ), msg( 0 ) {} 183 MsgEnvelope() : type( OneWay ), msg( 0 ) {}
182 MsgEnvelope( SendType _type , ChannelMessage *_msg ) 184 MsgEnvelope( SendType _type , ChannelMessage *_msg )
183 : type( _type ), msg( _msg ) {} 185 : type( _type ), msg( _msg ) {}
184 186
185 SendType type; 187 SendType type;
186 ChannelMessage *msg; 188 ChannelMessage *msg;
187 }; 189 };
188 190
189 void deliverOne( const MsgEnvelope &envelope ); 191 void deliverOne( const MsgEnvelope &envelope );
190 192
191 typedef QValueList<MsgEnvelope> MsgEnvelopeList; 193 typedef QValueList<MsgEnvelope> MsgEnvelopeList;
192 194
193 MsgEnvelopeList m_pendingMessages; 195 MsgEnvelopeList m_pendingMessages;
194 Mutex m_pendingMessagesGuard; 196 Mutex m_pendingMessagesGuard;
195 197
196 struct Private; 198 struct Private;
197 Private *d; 199 Private *d;
198 }; 200 };
199 201
200} 202}
201 203
202#endif // THREADUTIL_H 204#endif // THREADUTIL_H
203/* vim: et sw=4 ts=4 205/* vim: et sw=4 ts=4
204 */ 206 */