summaryrefslogtreecommitdiff
path: root/noncore/multimedia/opieplayer2/threadutil.cpp
Unidiff
Diffstat (limited to 'noncore/multimedia/opieplayer2/threadutil.cpp') (more/less context) (show whitespace changes)
-rw-r--r--noncore/multimedia/opieplayer2/threadutil.cpp99
1 files changed, 99 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
@@ -3,48 +3,49 @@
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 28
28using namespace ThreadUtil; 29using namespace ThreadUtil;
29 30
30struct Mutex::Data 31struct Mutex::Data
31{ 32{
32 Data() 33 Data()
33 { 34 {
34 pthread_mutex_init( &mutex, 0 ); 35 pthread_mutex_init( &mutex, 0 );
35 } 36 }
36 ~Data() 37 ~Data()
37 { 38 {
38 pthread_mutex_destroy( &mutex ); 39 pthread_mutex_destroy( &mutex );
39 } 40 }
40 41
41 pthread_mutex_t mutex; 42 pthread_mutex_t mutex;
42}; 43};
43 44
44Mutex::Mutex() 45Mutex::Mutex()
45 : d( new Data ) 46 : d( new Data )
46{ 47{
47} 48}
48 49
49Mutex::~Mutex() 50Mutex::~Mutex()
50{ 51{
@@ -101,48 +102,146 @@ WaitCondition::~WaitCondition()
101} 102}
102 103
103bool WaitCondition::wait() 104bool WaitCondition::wait()
104{ 105{
105 Mutex m; 106 Mutex m;
106 m.lock(); 107 m.lock();
107 return wait( m ); 108 return wait( m );
108} 109}
109 110
110bool WaitCondition::wait( Mutex &mutex ) 111bool WaitCondition::wait( Mutex &mutex )
111{ 112{
112 return pthread_cond_wait( &d->waitCondition, &mutex.d->mutex ); 113 return pthread_cond_wait( &d->waitCondition, &mutex.d->mutex );
113} 114}
114 115
115void WaitCondition::wakeOne() 116void WaitCondition::wakeOne()
116{ 117{
117 pthread_cond_signal( &d->waitCondition ); 118 pthread_cond_signal( &d->waitCondition );
118} 119}
119 120
120void WaitCondition::wakeAll() 121void WaitCondition::wakeAll()
121{ 122{
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 ];
128 pipe( fds ); 227 pipe( fds );
129 m_readFd = fds[ 0 ]; 228 m_readFd = fds[ 0 ];
130 m_writeFd = fds[ 1 ]; 229 m_writeFd = fds[ 1 ];
131 230
132 m_notifier = new QSocketNotifier( m_readFd, QSocketNotifier::Read ); 231 m_notifier = new QSocketNotifier( m_readFd, QSocketNotifier::Read );
133 connect( m_notifier, SIGNAL( activated( int ) ), 232 connect( m_notifier, SIGNAL( activated( int ) ),
134 this, SLOT( wakeUp() ) ); 233 this, SLOT( wakeUp() ) );
135} 234}
136 235
137OnewayNotifier::~OnewayNotifier() 236OnewayNotifier::~OnewayNotifier()
138{ 237{
139 delete m_notifier; 238 delete m_notifier;
140 239
141 ::close( m_readFd ); 240 ::close( m_readFd );
142 ::close( m_writeFd ); 241 ::close( m_writeFd );
143} 242}
144 243
145void OnewayNotifier::notify() 244void OnewayNotifier::notify()
146{ 245{
147 const char c = 42; 246 const char c = 42;
148 ::write( m_writeFd, &c, 1 ); 247 ::write( m_writeFd, &c, 1 );