summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/multimedia/opieplayer2/skin.cpp1
-rw-r--r--noncore/multimedia/opieplayer2/threadutil.cpp1
2 files changed, 2 insertions, 0 deletions
diff --git a/noncore/multimedia/opieplayer2/skin.cpp b/noncore/multimedia/opieplayer2/skin.cpp
index 84f5f87..5d8929e 100644
--- a/noncore/multimedia/opieplayer2/skin.cpp
+++ b/noncore/multimedia/opieplayer2/skin.cpp
@@ -1,216 +1,217 @@
1/* 1/*
2 Copyright (C) 2002 Simon Hausmann <simon@lst.de> 2 Copyright (C) 2002 Simon Hausmann <simon@lst.de>
3 (C) 2002 Max Reiss <harlekin@handhelds.org> 3 (C) 2002 Max Reiss <harlekin@handhelds.org>
4 (C) 2002 L. Potter <ljp@llornkcor.com> 4 (C) 2002 L. Potter <ljp@llornkcor.com>
5 (C) 2002 Holger Freyther <zecke@handhelds.org> 5 (C) 2002 Holger Freyther <zecke@handhelds.org>
6 6
7 This program is free software; you can redistribute it and/or 7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public 8 modify it under the terms of the GNU General Public
9 License as published by the Free Software Foundation; either 9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version. 10 version 2 of the License, or (at your option) any later version.
11 11
12 This program is distributed in the hope that it will be useful, 12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details. 15 General Public License for more details.
16 16
17 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
18 along with this program; see the file COPYING. If not, write to 18 along with this program; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. 20 Boston, MA 02111-1307, USA.
21*/ 21*/
22 22
23#include "skin.h" 23#include "skin.h"
24#include "singleton.h" 24#include "singleton.h"
25#include <opie2/odebug.h>
25 26
26#include <qcache.h> 27#include <qcache.h>
27#include <qtimer.h> 28#include <qtimer.h>
28 29
29#include <qpe/config.h> 30#include <qpe/config.h>
30 31
31#include <assert.h> 32#include <assert.h>
32 33
33struct SkinData 34struct SkinData
34{ 35{
35 typedef QMap<QString, QImage> ButtonMaskImageMap; 36 typedef QMap<QString, QImage> ButtonMaskImageMap;
36 37
37 QPixmap backgroundPixmap; 38 QPixmap backgroundPixmap;
38 QImage buttonUpImage; 39 QImage buttonUpImage;
39 QImage buttonDownImage; 40 QImage buttonDownImage;
40 QImage buttonMask; 41 QImage buttonMask;
41 ButtonMaskImageMap buttonMasks; 42 ButtonMaskImageMap buttonMasks;
42}; 43};
43 44
44class SkinCache : public Singleton<SkinCache> 45class SkinCache : public Singleton<SkinCache>
45{ 46{
46public: 47public:
47 SkinCache(); 48 SkinCache();
48 49
49 SkinData *lookupAndTake( const QString &skinPath, const QString &fileNameInfix ); 50 SkinData *lookupAndTake( const QString &skinPath, const QString &fileNameInfix );
50 51
51 void store( const QString &skinPath, const QString &fileNameInfix, SkinData *data ); 52 void store( const QString &skinPath, const QString &fileNameInfix, SkinData *data );
52 53
53private: 54private:
54 typedef QCache<SkinData> DataCache; 55 typedef QCache<SkinData> DataCache;
55 typedef QCache<QPixmap> BackgroundPixmapCache; 56 typedef QCache<QPixmap> BackgroundPixmapCache;
56 57
57 template <class CacheType> 58 template <class CacheType>
58 void store( const QCache<CacheType> &cache, const QString &key, CacheType *data ); 59 void store( const QCache<CacheType> &cache, const QString &key, CacheType *data );
59 60
60 DataCache m_cache; 61 DataCache m_cache;
61 BackgroundPixmapCache m_backgroundPixmapCache; 62 BackgroundPixmapCache m_backgroundPixmapCache;
62}; 63};
63 64
64Skin::Skin( const QString &name, const QString &fileNameInfix ) 65Skin::Skin( const QString &name, const QString &fileNameInfix )
65 : m_fileNameInfix( fileNameInfix ) 66 : m_fileNameInfix( fileNameInfix )
66{ 67{
67 init( name ); 68 init( name );
68} 69}
69 70
70Skin::Skin( const QString &fileNameInfix ) 71Skin::Skin( const QString &fileNameInfix )
71 : m_fileNameInfix( fileNameInfix ) 72 : m_fileNameInfix( fileNameInfix )
72{ 73{
73 init( defaultSkinName() ); 74 init( defaultSkinName() );
74} 75}
75 76
76Skin::~Skin() 77Skin::~Skin()
77{ 78{
78 if ( m_isCachable ) 79 if ( m_isCachable )
79 SkinCache::self().store( m_skinPath, m_fileNameInfix, d ); 80 SkinCache::self().store( m_skinPath, m_fileNameInfix, d );
80 else 81 else
81 delete d; 82 delete d;
82} 83}
83 84
84void Skin::init( const QString &name ) 85void Skin::init( const QString &name )
85{ 86{
86 m_isCachable = true; 87 m_isCachable = true;
87 m_skinPath = "opieplayer2/skins/" + name; 88 m_skinPath = "opieplayer2/skins/" + name;
88 d = SkinCache::self().lookupAndTake( m_skinPath, m_fileNameInfix ); 89 d = SkinCache::self().lookupAndTake( m_skinPath, m_fileNameInfix );
89} 90}
90 91
91QPixmap Skin::backgroundPixmap() const 92QPixmap Skin::backgroundPixmap() const
92{ 93{
93 if ( d->backgroundPixmap.isNull() ) 94 if ( d->backgroundPixmap.isNull() )
94 d->backgroundPixmap = loadImage( QString( "%1/background" ).arg( m_skinPath ) ); 95 d->backgroundPixmap = loadImage( QString( "%1/background" ).arg( m_skinPath ) );
95 return d->backgroundPixmap; 96 return d->backgroundPixmap;
96} 97}
97 98
98QImage Skin::buttonUpImage() const 99QImage Skin::buttonUpImage() const
99{ 100{
100 if ( d->buttonUpImage.isNull() ) 101 if ( d->buttonUpImage.isNull() )
101 d->buttonUpImage = loadImage( QString( "%1/skin%2_up" ).arg( m_skinPath ).arg( m_fileNameInfix ) ); 102 d->buttonUpImage = loadImage( QString( "%1/skin%2_up" ).arg( m_skinPath ).arg( m_fileNameInfix ) );
102 return d->buttonUpImage; 103 return d->buttonUpImage;
103} 104}
104 105
105QImage Skin::buttonDownImage() const 106QImage Skin::buttonDownImage() const
106{ 107{
107 if ( d->buttonDownImage.isNull() ) 108 if ( d->buttonDownImage.isNull() )
108 d->buttonDownImage = loadImage( QString( "%1/skin%2_down" ).arg( m_skinPath ).arg( m_fileNameInfix ) ); 109 d->buttonDownImage = loadImage( QString( "%1/skin%2_down" ).arg( m_skinPath ).arg( m_fileNameInfix ) );
109 return d->buttonDownImage; 110 return d->buttonDownImage;
110} 111}
111 112
112QImage Skin::buttonMask( const MediaWidget::SkinButtonInfo *skinButtonInfo, uint buttonCount ) const 113QImage Skin::buttonMask( const MediaWidget::SkinButtonInfo *skinButtonInfo, uint buttonCount ) const
113{ 114{
114 if ( !d->buttonMask.isNull() ) 115 if ( !d->buttonMask.isNull() )
115 return d->buttonMask; 116 return d->buttonMask;
116 117
117 QSize buttonAreaSize = buttonUpImage().size(); 118 QSize buttonAreaSize = buttonUpImage().size();
118 119
119 d->buttonMask = QImage( buttonAreaSize, 8, 255 ); 120 d->buttonMask = QImage( buttonAreaSize, 8, 255 );
120 d->buttonMask.fill( 0 ); 121 d->buttonMask.fill( 0 );
121 122
122 for ( uint i = 0; i < buttonCount; ++i ) 123 for ( uint i = 0; i < buttonCount; ++i )
123 addButtonToMask( skinButtonInfo[ i ].command + 1, buttonMaskImage( skinButtonInfo[ i ].fileName ) ); 124 addButtonToMask( skinButtonInfo[ i ].command + 1, buttonMaskImage( skinButtonInfo[ i ].fileName ) );
124 125
125 return d->buttonMask; 126 return d->buttonMask;
126} 127}
127 128
128void Skin::addButtonToMask( int tag, const QImage &maskImage ) const 129void Skin::addButtonToMask( int tag, const QImage &maskImage ) const
129{ 130{
130 if ( maskImage.isNull() ) 131 if ( maskImage.isNull() )
131 return; 132 return;
132 133
133 uchar **dest = d->buttonMask.jumpTable(); 134 uchar **dest = d->buttonMask.jumpTable();
134 for ( int y = 0; y < d->buttonMask.height(); y++ ) { 135 for ( int y = 0; y < d->buttonMask.height(); y++ ) {
135 uchar *line = dest[y]; 136 uchar *line = dest[y];
136 for ( int x = 0; x < d->buttonMask.width(); x++ ) 137 for ( int x = 0; x < d->buttonMask.width(); x++ )
137 if ( !qRed( maskImage.pixel( x, y ) ) ) 138 if ( !qRed( maskImage.pixel( x, y ) ) )
138 line[x] = tag; 139 line[x] = tag;
139 } 140 }
140} 141}
141 142
142QImage Skin::buttonMaskImage( const QString &fileName ) const 143QImage Skin::buttonMaskImage( const QString &fileName ) const
143{ 144{
144 SkinData::ButtonMaskImageMap::Iterator it = d->buttonMasks.find( fileName ); 145 SkinData::ButtonMaskImageMap::Iterator it = d->buttonMasks.find( fileName );
145 if ( it == d->buttonMasks.end() ) { 146 if ( it == d->buttonMasks.end() ) {
146 QString prefix = m_skinPath + QString::fromLatin1( "/skin%1_mask_" ).arg( m_fileNameInfix ); 147 QString prefix = m_skinPath + QString::fromLatin1( "/skin%1_mask_" ).arg( m_fileNameInfix );
147 QString path = prefix + fileName; 148 QString path = prefix + fileName;
148 it = d->buttonMasks.insert( fileName, loadImage( path ) ); 149 it = d->buttonMasks.insert( fileName, loadImage( path ) );
149 } 150 }
150 return *it; 151 return *it;
151} 152}
152 153
153QString Skin::defaultSkinName() 154QString Skin::defaultSkinName()
154{ 155{
155 Config cfg( "OpiePlayer" ); 156 Config cfg( "OpiePlayer" );
156 cfg.setGroup( "Options" ); 157 cfg.setGroup( "Options" );
157 return cfg.readEntry( "Skin", "default" ); 158 return cfg.readEntry( "Skin", "default" );
158} 159}
159 160
160QImage Skin::loadImage( const QString &fileName ) 161QImage Skin::loadImage( const QString &fileName )
161{ 162{
162 return QImage( Resource::findPixmap( fileName ) ); 163 return QImage( Resource::findPixmap( fileName ) );
163} 164}
164 165
165SkinCache::SkinCache() 166SkinCache::SkinCache()
166{ 167{
167 // let's say we cache two skins (audio+video) at maximum 168 // let's say we cache two skins (audio+video) at maximum
168 m_cache.setMaxCost( 2 ); 169 m_cache.setMaxCost( 2 );
169 // ... and one background pixmap 170 // ... and one background pixmap
170 m_backgroundPixmapCache.setMaxCost( 1 ); 171 m_backgroundPixmapCache.setMaxCost( 1 );
171} 172}
172 173
173SkinData *SkinCache::lookupAndTake( const QString &skinPath, const QString &fileNameInfix ) 174SkinData *SkinCache::lookupAndTake( const QString &skinPath, const QString &fileNameInfix )
174{ 175{
175 QString key = skinPath + fileNameInfix; 176 QString key = skinPath + fileNameInfix;
176 177
177 SkinData *data = m_cache.take( key ); 178 SkinData *data = m_cache.take( key );
178 if ( !data ) 179 if ( !data )
179 data = new SkinData; 180 data = new SkinData;
180 else 181 else
181 odebug << "SkinCache: hit" << oendl; 182 odebug << "SkinCache: hit" << oendl;
182 183
183 QPixmap *bgPixmap = m_backgroundPixmapCache.find( skinPath ); 184 QPixmap *bgPixmap = m_backgroundPixmapCache.find( skinPath );
184 if ( bgPixmap ) { 185 if ( bgPixmap ) {
185 odebug << "SkinCache: hit on bgpixmap" << oendl; 186 odebug << "SkinCache: hit on bgpixmap" << oendl;
186 data->backgroundPixmap = *bgPixmap; 187 data->backgroundPixmap = *bgPixmap;
187 } 188 }
188 else 189 else
189 data->backgroundPixmap = QPixmap(); 190 data->backgroundPixmap = QPixmap();
190 191
191 return data; 192 return data;
192} 193}
193 194
194void SkinCache::store( const QString &skinPath, const QString &fileNameInfix, SkinData *data ) 195void SkinCache::store( const QString &skinPath, const QString &fileNameInfix, SkinData *data )
195{ 196{
196 QPixmap *backgroundPixmap = new QPixmap( data->backgroundPixmap ); 197 QPixmap *backgroundPixmap = new QPixmap( data->backgroundPixmap );
197 198
198 data->backgroundPixmap = QPixmap(); 199 data->backgroundPixmap = QPixmap();
199 200
200 QString key = skinPath + fileNameInfix; 201 QString key = skinPath + fileNameInfix;
201 202
202 if ( m_cache.find( key, false /*ref*/ ) != 0 || 203 if ( m_cache.find( key, false /*ref*/ ) != 0 ||
203 !m_cache.insert( key, data ) ) 204 !m_cache.insert( key, data ) )
204 delete data; 205 delete data;
205 206
206 if ( m_backgroundPixmapCache.find( skinPath, false /*ref*/ ) != 0 || 207 if ( m_backgroundPixmapCache.find( skinPath, false /*ref*/ ) != 0 ||
207 !m_backgroundPixmapCache.insert( skinPath, backgroundPixmap ) ) 208 !m_backgroundPixmapCache.insert( skinPath, backgroundPixmap ) )
208 delete backgroundPixmap; 209 delete backgroundPixmap;
209} 210}
210 211
211SkinLoader::IncrementalLoader::IncrementalLoader( const Info &info ) 212SkinLoader::IncrementalLoader::IncrementalLoader( const Info &info )
212 : m_skin( info.skinName, info.fileNameInfix ), m_info( info ) 213 : m_skin( info.skinName, info.fileNameInfix ), m_info( info )
213{ 214{
214 m_currentState = LoadBackgroundPixmap; 215 m_currentState = LoadBackgroundPixmap;
215} 216}
216 217
diff --git a/noncore/multimedia/opieplayer2/threadutil.cpp b/noncore/multimedia/opieplayer2/threadutil.cpp
index d8b8abe..6ed9853 100644
--- a/noncore/multimedia/opieplayer2/threadutil.cpp
+++ b/noncore/multimedia/opieplayer2/threadutil.cpp
@@ -1,213 +1,214 @@
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 <opie2/odebug.h>
22#include <qsocketnotifier.h> 23#include <qsocketnotifier.h>
23 24
24#include <pthread.h> 25#include <pthread.h>
25#include <assert.h> 26#include <assert.h>
26#include <unistd.h> 27#include <unistd.h>
27#include <errno.h> 28#include <errno.h>
28 29
29using namespace ThreadUtil; 30using namespace ThreadUtil;
30 31
31struct Mutex::Data 32struct Mutex::Data
32{ 33{
33 Data() 34 Data()
34 { 35 {
35 pthread_mutex_init( &mutex, 0 ); 36 pthread_mutex_init( &mutex, 0 );
36 } 37 }
37 ~Data() 38 ~Data()
38 { 39 {
39 pthread_mutex_destroy( &mutex ); 40 pthread_mutex_destroy( &mutex );
40 } 41 }
41 42
42 pthread_mutex_t mutex; 43 pthread_mutex_t mutex;
43}; 44};
44 45
45Mutex::Mutex() 46Mutex::Mutex()
46 : d( new Data ) 47 : d( new Data )
47{ 48{
48} 49}
49 50
50Mutex::~Mutex() 51Mutex::~Mutex()
51{ 52{
52 delete d; 53 delete d;
53} 54}
54 55
55void Mutex::lock() 56void Mutex::lock()
56{ 57{
57 pthread_mutex_lock( &d->mutex ); 58 pthread_mutex_lock( &d->mutex );
58} 59}
59 60
60void Mutex::unlock() 61void Mutex::unlock()
61{ 62{
62 pthread_mutex_unlock( &d->mutex ); 63 pthread_mutex_unlock( &d->mutex );
63} 64}
64 65
65bool Mutex::tryLock() 66bool Mutex::tryLock()
66{ 67{
67 return pthread_mutex_trylock( &d->mutex ) == 0; 68 return pthread_mutex_trylock( &d->mutex ) == 0;
68} 69}
69 70
70bool Mutex::isLocked() 71bool Mutex::isLocked()
71{ 72{
72 if ( !tryLock() ) 73 if ( !tryLock() )
73 return true; 74 return true;
74 75
75 unlock(); 76 unlock();
76 return false; 77 return false;
77} 78}
78 79
79struct WaitCondition::Data 80struct WaitCondition::Data
80{ 81{
81 Data() 82 Data()
82 { 83 {
83 int result = pthread_cond_init( &waitCondition, 0 ); 84 int result = pthread_cond_init( &waitCondition, 0 );
84 assert( result == 0 ); 85 assert( result == 0 );
85 } 86 }
86 ~Data() 87 ~Data()
87 { 88 {
88 pthread_cond_destroy( &waitCondition ); 89 pthread_cond_destroy( &waitCondition );
89 } 90 }
90 91
91 pthread_cond_t waitCondition; 92 pthread_cond_t waitCondition;
92}; 93};
93 94
94WaitCondition::WaitCondition() 95WaitCondition::WaitCondition()
95 : d( new Data ) 96 : d( new Data )
96{ 97{
97} 98}
98 99
99WaitCondition::~WaitCondition() 100WaitCondition::~WaitCondition()
100{ 101{
101 delete d; 102 delete d;
102} 103}
103 104
104bool WaitCondition::wait() 105bool WaitCondition::wait()
105{ 106{
106 Mutex m; 107 Mutex m;
107 m.lock(); 108 m.lock();
108 return wait( m ); 109 return wait( m );
109} 110}
110 111
111bool WaitCondition::wait( Mutex &mutex ) 112bool WaitCondition::wait( Mutex &mutex )
112{ 113{
113 return pthread_cond_wait( &d->waitCondition, &mutex.d->mutex ); 114 return pthread_cond_wait( &d->waitCondition, &mutex.d->mutex );
114} 115}
115 116
116void WaitCondition::wakeOne() 117void WaitCondition::wakeOne()
117{ 118{
118 pthread_cond_signal( &d->waitCondition ); 119 pthread_cond_signal( &d->waitCondition );
119} 120}
120 121
121void WaitCondition::wakeAll() 122void WaitCondition::wakeAll()
122{ 123{
123 pthread_cond_broadcast( &d->waitCondition ); 124 pthread_cond_broadcast( &d->waitCondition );
124} 125}
125 126
126struct Thread::Data 127struct Thread::Data
127{ 128{
128 Data() : isRunning( false ) 129 Data() : isRunning( false )
129 {} 130 {}
130 131
131 pthread_t self; 132 pthread_t self;
132 Mutex guard; 133 Mutex guard;
133 bool isRunning; 134 bool isRunning;
134 135
135 WaitCondition finishCondition; 136 WaitCondition finishCondition;
136 137
137 Thread *thr; 138 Thread *thr;
138 139
139 void run() { thr->run(); } 140 void run() { thr->run(); }
140}; 141};
141 142
142extern "C" 143extern "C"
143{ 144{
144 145
145static void terminate_thread( void *arg ) 146static void terminate_thread( void *arg )
146{ 147{
147 Thread::Data *data = ( Thread::Data* )arg; 148 Thread::Data *data = ( Thread::Data* )arg;
148 149
149 assert( data ); 150 assert( data );
150 151
151 AutoLock locker( data->guard ); 152 AutoLock locker( data->guard );
152 data->isRunning = false; 153 data->isRunning = false;
153 data->finishCondition.wakeAll(); 154 data->finishCondition.wakeAll();
154} 155}
155 156
156static void *start_thread( void *arg ) 157static void *start_thread( void *arg )
157{ 158{
158 Thread::Data *data = ( Thread::Data* )arg; 159 Thread::Data *data = ( Thread::Data* )arg;
159 160
160 pthread_cleanup_push( terminate_thread, data ); 161 pthread_cleanup_push( terminate_thread, data );
161 162
162 data->isRunning = true; 163 data->isRunning = true;
163 data->run(); 164 data->run();
164 165
165 pthread_cleanup_pop( true ); 166 pthread_cleanup_pop( true );
166 167
167 Thread::exit(); 168 Thread::exit();
168 return 0; // never reached 169 return 0; // never reached
169} 170}
170 171
171} 172}
172 173
173Thread::Thread() 174Thread::Thread()
174 : d( new Data ) 175 : d( new Data )
175{ 176{
176 d->thr = this; 177 d->thr = this;
177} 178}
178 179
179Thread::~Thread() 180Thread::~Thread()
180{ 181{
181 assert( d->isRunning == false ); 182 assert( d->isRunning == false );
182 delete d; 183 delete d;
183} 184}
184 185
185void Thread::start() 186void Thread::start()
186{ 187{
187 AutoLock lock( d->guard ); 188 AutoLock lock( d->guard );
188 189
189 if ( d->isRunning ) { 190 if ( d->isRunning ) {
190 odebug << "ThreadUtil::Thread::start() called for running thread." << oendl; 191 odebug << "ThreadUtil::Thread::start() called for running thread." << oendl;
191 return; 192 return;
192 } 193 }
193 194
194 pthread_attr_t attributes; 195 pthread_attr_t attributes;
195 pthread_attr_init( &attributes ); 196 pthread_attr_init( &attributes );
196 pthread_attr_setscope( &attributes, PTHREAD_SCOPE_SYSTEM ); 197 pthread_attr_setscope( &attributes, PTHREAD_SCOPE_SYSTEM );
197 int err = pthread_create( &d->self, &attributes, start_thread, ( void* )d ); 198 int err = pthread_create( &d->self, &attributes, start_thread, ( void* )d );
198 if ( err != 0 ) { 199 if ( err != 0 ) {
199 odebug << "ThreadUtil::Thread::start() : can't create thread: " << strerror( err ) << "" << oendl; 200 odebug << "ThreadUtil::Thread::start() : can't create thread: " << strerror( err ) << "" << oendl;
200 pthread_attr_destroy( &attributes ); 201 pthread_attr_destroy( &attributes );
201 return; 202 return;
202 } 203 }
203 pthread_attr_destroy( &attributes ); 204 pthread_attr_destroy( &attributes );
204} 205}
205 206
206void Thread::terminate() 207void Thread::terminate()
207{ 208{
208 AutoLock lock( d->guard ); 209 AutoLock lock( d->guard );
209 if ( !d->isRunning ) 210 if ( !d->isRunning )
210 return; 211 return;
211 212
212 pthread_cancel( d->self ); 213 pthread_cancel( d->self );
213} 214}