summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/multimedia/opieplayer2/threadutil.cpp14
-rw-r--r--noncore/multimedia/opieplayer2/threadutil.h5
2 files changed, 9 insertions, 10 deletions
diff --git a/noncore/multimedia/opieplayer2/threadutil.cpp b/noncore/multimedia/opieplayer2/threadutil.cpp
index a5cc92d..7a9e1a4 100644
--- a/noncore/multimedia/opieplayer2/threadutil.cpp
+++ b/noncore/multimedia/opieplayer2/threadutil.cpp
@@ -13,272 +13,272 @@
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 ) 141static void terminate_thread( void *arg )
142{ 142{
143 Thread *thr = ( Thread* )arg; 143 Thread::Data *data = ( Thread::Data* )arg;
144 144
145 assert( thr ); 145 assert( data );
146 146
147 AutoLock locker( thr->d->guard ); 147 AutoLock locker( data->guard );
148 thr->d->isRunning = false; 148 data->isRunning = false;
149 thr->d->finishCondition.wakeAll(); 149 data->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( terminate_thread, thr->d );
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 219bool Thread::isRunning() const
220{ 220{
221 AutoLock lock( d->guard ); 221 AutoLock lock( d->guard );
222 return d->isRunning; 222 return d->isRunning;
223} 223}
224 224
225void Thread::exit() 225void Thread::exit()
226{ 226{
227 pthread_exit( 0 ); 227 pthread_exit( 0 );
228} 228}
229 229
230OnewayNotifier::OnewayNotifier() 230OnewayNotifier::OnewayNotifier()
231{ 231{
232 int fds[ 2 ]; 232 int fds[ 2 ];
233 pipe( fds ); 233 pipe( fds );
234 m_readFd = fds[ 0 ]; 234 m_readFd = fds[ 0 ];
235 m_writeFd = fds[ 1 ]; 235 m_writeFd = fds[ 1 ];
236 236
237 m_notifier = new QSocketNotifier( m_readFd, QSocketNotifier::Read ); 237 m_notifier = new QSocketNotifier( m_readFd, QSocketNotifier::Read );
238 connect( m_notifier, SIGNAL( activated( int ) ), 238 connect( m_notifier, SIGNAL( activated( int ) ),
239 this, SLOT( wakeUp() ) ); 239 this, SLOT( wakeUp() ) );
240} 240}
241 241
242OnewayNotifier::~OnewayNotifier() 242OnewayNotifier::~OnewayNotifier()
243{ 243{
244 delete m_notifier; 244 delete m_notifier;
245 245
246 ::close( m_readFd ); 246 ::close( m_readFd );
247 ::close( m_writeFd ); 247 ::close( m_writeFd );
248} 248}
249 249
250void OnewayNotifier::notify() 250void OnewayNotifier::notify()
251{ 251{
252 const char c = 42; 252 const char c = 42;
253 ::write( m_writeFd, &c, 1 ); 253 ::write( m_writeFd, &c, 1 );
254} 254}
255 255
256void OnewayNotifier::wakeUp() 256void OnewayNotifier::wakeUp()
257{ 257{
258 char c = 0; 258 char c = 0;
259 259
260 if ( ::read( m_readFd, &c, 1 ) != 1 ) 260 if ( ::read( m_readFd, &c, 1 ) != 1 )
261 return; 261 return;
262 262
263 emit awake(); 263 emit awake();
264} 264}
265 265
266ChannelMessage::ChannelMessage( int type ) 266ChannelMessage::ChannelMessage( int type )
267 : m_type( type ), m_isCall( false ), m_replied( false ), 267 : m_type( type ), m_isCall( false ), m_replied( false ),
268 m_inEventHandler( false ) 268 m_inEventHandler( false )
269{ 269{
270} 270}
271 271
272ChannelMessage::~ChannelMessage() 272ChannelMessage::~ChannelMessage()
273{ 273{
274 if ( m_guard.isLocked() ) 274 if ( m_guard.isLocked() )
275 m_guard.unlock(); 275 m_guard.unlock();
276} 276}
277 277
278void ChannelMessage::reply() 278void ChannelMessage::reply()
279{ 279{
280 if ( !m_isCall ) 280 if ( !m_isCall )
281 { 281 {
282 qDebug( "ChannelMessage::reply() - can't reply oneway message!" ); 282 qDebug( "ChannelMessage::reply() - can't reply oneway message!" );
283 return; 283 return;
284 } 284 }
diff --git a/noncore/multimedia/opieplayer2/threadutil.h b/noncore/multimedia/opieplayer2/threadutil.h
index b67b61d..21ae6b2 100644
--- a/noncore/multimedia/opieplayer2/threadutil.h
+++ b/noncore/multimedia/opieplayer2/threadutil.h
@@ -1,206 +1,205 @@
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* );
33} 32}
34 33
35namespace ThreadUtil 34namespace ThreadUtil
36{ 35{
37 36
38 class Mutex 37 class Mutex
39 { 38 {
40 friend class WaitCondition; 39 friend class WaitCondition;
41 public: 40 public:
42 Mutex(); 41 Mutex();
43 ~Mutex(); 42 ~Mutex();
44 43
45 void lock(); 44 void lock();
46 void unlock(); 45 void unlock();
47 bool tryLock(); 46 bool tryLock();
48 bool isLocked(); 47 bool isLocked();
49 48
50 private: 49 private:
51 struct Data; 50 struct Data;
52 Data *d; 51 Data *d;
53 52
54 Mutex( const Mutex & ); 53 Mutex( const Mutex & );
55 Mutex &operator=( const Mutex & ); 54 Mutex &operator=( const Mutex & );
56 }; 55 };
57 56
58 class AutoLock 57 class AutoLock
59 { 58 {
60 public: 59 public:
61 AutoLock( Mutex &mutex ) : m_mutex( mutex ) { m_mutex.lock(); } 60 AutoLock( Mutex &mutex ) : m_mutex( mutex ) { m_mutex.lock(); }
62 ~AutoLock() { m_mutex.unlock(); } 61 ~AutoLock() { m_mutex.unlock(); }
63 62
64 Mutex *operator &() const { return &m_mutex; } 63 Mutex *operator &() const { return &m_mutex; }
65 64
66 private: 65 private:
67 Mutex &m_mutex; 66 Mutex &m_mutex;
68 }; 67 };
69 68
70 class WaitCondition 69 class WaitCondition
71 { 70 {
72 public: 71 public:
73 WaitCondition(); 72 WaitCondition();
74 ~WaitCondition(); 73 ~WaitCondition();
75 74
76 bool wait(); 75 bool wait();
77 bool wait( Mutex &mutex ); 76 bool wait( Mutex &mutex );
78 77
79 void wakeOne(); 78 void wakeOne();
80 void wakeAll(); 79 void wakeAll();
81 80
82 private: 81 private:
83 struct Data; 82 struct Data;
84 Data *d; 83 Data *d;
85 84
86 WaitCondition( const WaitCondition & ); 85 WaitCondition( const WaitCondition & );
87 WaitCondition &operator=( const WaitCondition & ); 86 WaitCondition &operator=( const WaitCondition & );
88 }; 87 };
89 88
90 class Thread 89 class Thread
91 { 90 {
92 friend void *::_threadutil_start_thread( void* ); 91 friend void *::_threadutil_start_thread( void* );
93 friend void ::_threadutil_terminate_thread( void* );
94 public: 92 public:
93 struct Data;
94
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; 103 bool isRunning() const;
104 104
105 static void exit(); 105 static void exit();
106 protected: 106 protected:
107 virtual void run() = 0; 107 virtual void run() = 0;
108 108
109 private: 109 private:
110 struct Data;
111 Data *d; 110 Data *d;
112 }; 111 };
113 112
114 class OnewayNotifier : public QObject 113 class OnewayNotifier : public QObject
115 { 114 {
116 Q_OBJECT 115 Q_OBJECT
117 public: 116 public:
118 OnewayNotifier(); 117 OnewayNotifier();
119 ~OnewayNotifier(); 118 ~OnewayNotifier();
120 119
121 void notify(); 120 void notify();
122 121
123 signals: 122 signals:
124 void awake(); 123 void awake();
125 124
126 private slots: 125 private slots:
127 void wakeUp(); 126 void wakeUp();
128 127
129 private: 128 private:
130 int m_readFd; 129 int m_readFd;
131 int m_writeFd; 130 int m_writeFd;
132 QSocketNotifier *m_notifier; 131 QSocketNotifier *m_notifier;
133 }; 132 };
134 133
135 134
136 class Channel; 135 class Channel;
137 136
138 class ChannelMessage 137 class ChannelMessage
139 { 138 {
140 friend class Channel; 139 friend class Channel;
141 public: 140 public:
142 ChannelMessage( int type = -1 ); 141 ChannelMessage( int type = -1 );
143 virtual ~ChannelMessage(); 142 virtual ~ChannelMessage();
144 143
145 int type() const { return m_type; } 144 int type() const { return m_type; }
146 145
147 void reply(); 146 void reply();
148 147
149 private: 148 private:
150 ChannelMessage( const ChannelMessage & ); 149 ChannelMessage( const ChannelMessage & );
151 ChannelMessage &operator=( const ChannelMessage ); 150 ChannelMessage &operator=( const ChannelMessage );
152 151
153 int m_type; 152 int m_type;
154 bool m_isCall : 1; 153 bool m_isCall : 1;
155 bool m_replied : 1; 154 bool m_replied : 1;
156 bool m_inEventHandler : 1; 155 bool m_inEventHandler : 1;
157 Mutex m_guard; 156 Mutex m_guard;
158 WaitCondition m_condition; 157 WaitCondition m_condition;
159 QGuardedPtr<Channel> m_channel; 158 QGuardedPtr<Channel> m_channel;
160 }; 159 };
161 160
162 class Channel : public QObject 161 class Channel : public QObject
163 { 162 {
164 Q_OBJECT 163 Q_OBJECT
165 public: 164 public:
166 enum SendType { OneWay, WaitForReply }; 165 enum SendType { OneWay, WaitForReply };
167 Channel( QObject *parent = 0, const char *name = 0 ); 166 Channel( QObject *parent = 0, const char *name = 0 );
168 virtual ~Channel(); 167 virtual ~Channel();
169 168
170 void send( ChannelMessage *message, SendType type ); 169 void send( ChannelMessage *message, SendType type );
171 170
172 protected: 171 protected:
173 virtual void receiveMessage( ChannelMessage *message, SendType type ) = 0; 172 virtual void receiveMessage( ChannelMessage *message, SendType type ) = 0;
174 173
175 private slots: 174 private slots:
176 void deliver(); 175 void deliver();
177 176
178 private: 177 private:
179 OnewayNotifier m_notifier; 178 OnewayNotifier m_notifier;
180 179
181 struct MsgEnvelope 180 struct MsgEnvelope
182 { 181 {
183 MsgEnvelope() : type( OneWay ), msg( 0 ) {} 182 MsgEnvelope() : type( OneWay ), msg( 0 ) {}
184 MsgEnvelope( SendType _type , ChannelMessage *_msg ) 183 MsgEnvelope( SendType _type , ChannelMessage *_msg )
185 : type( _type ), msg( _msg ) {} 184 : type( _type ), msg( _msg ) {}
186 185
187 SendType type; 186 SendType type;
188 ChannelMessage *msg; 187 ChannelMessage *msg;
189 }; 188 };
190 189
191 void deliverOne( const MsgEnvelope &envelope ); 190 void deliverOne( const MsgEnvelope &envelope );
192 191
193 typedef QValueList<MsgEnvelope> MsgEnvelopeList; 192 typedef QValueList<MsgEnvelope> MsgEnvelopeList;
194 193
195 MsgEnvelopeList m_pendingMessages; 194 MsgEnvelopeList m_pendingMessages;
196 Mutex m_pendingMessagesGuard; 195 Mutex m_pendingMessagesGuard;
197 196
198 struct Private; 197 struct Private;
199 Private *d; 198 Private *d;
200 }; 199 };
201 200
202} 201}
203 202
204#endif // THREADUTIL_H 203#endif // THREADUTIL_H
205/* vim: et sw=4 ts=4 204/* vim: et sw=4 ts=4
206 */ 205 */