-rw-r--r-- | noncore/multimedia/opieplayer2/threadutil.cpp | 6 | ||||
-rw-r--r-- | noncore/multimedia/opieplayer2/threadutil.h | 2 |
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 @@ -155,128 +155,134 @@ void *_threadutil_start_thread( void *arg ) pthread_cleanup_push( _threadutil_terminate_thread, thr ); thr->d->isRunning = true; thr->run(); pthread_cleanup_pop( true ); Thread::exit(); return 0; // never reached } } Thread::Thread() : d( new Data ) { } Thread::~Thread() { assert( d->isRunning == false ); delete d; } void Thread::start() { AutoLock lock( d->guard ); if ( d->isRunning ) { qDebug( "ThreadUtil::Thread::start() called for running thread." ); return; } pthread_attr_t attributes; pthread_attr_init( &attributes ); pthread_attr_setscope( &attributes, PTHREAD_SCOPE_SYSTEM ); int err = pthread_create( &d->self, &attributes, _threadutil_start_thread, ( void* )this ); if ( err != 0 ) { qDebug( "ThreadUtil::Thread::start() : can't create thread: %s", strerror( err ) ); pthread_attr_destroy( &attributes ); return; } pthread_attr_destroy( &attributes ); } void Thread::terminate() { AutoLock lock( d->guard ); if ( !d->isRunning ) return; pthread_cancel( d->self ); } bool Thread::wait() { AutoLock lock( d->guard ); if ( !d->isRunning ) return true; return d->finishCondition.wait( d->guard ); } +bool Thread::isRunning() const +{ + AutoLock lock( d->guard ); + return d->isRunning; +} + void Thread::exit() { pthread_exit( 0 ); } OnewayNotifier::OnewayNotifier() { int fds[ 2 ]; pipe( fds ); m_readFd = fds[ 0 ]; m_writeFd = fds[ 1 ]; m_notifier = new QSocketNotifier( m_readFd, QSocketNotifier::Read ); connect( m_notifier, SIGNAL( activated( int ) ), this, SLOT( wakeUp() ) ); } OnewayNotifier::~OnewayNotifier() { delete m_notifier; ::close( m_readFd ); ::close( m_writeFd ); } void OnewayNotifier::notify() { const char c = 42; ::write( m_writeFd, &c, 1 ); } void OnewayNotifier::wakeUp() { char c = 0; if ( ::read( m_readFd, &c, 1 ) != 1 ) return; emit awake(); } ChannelMessage::ChannelMessage( int type ) : m_type( type ), m_isCall( false ), m_replied( false ), m_inEventHandler( false ) { } ChannelMessage::~ChannelMessage() { if ( m_guard.isLocked() ) m_guard.unlock(); } void ChannelMessage::reply() { if ( !m_isCall ) { qDebug( "ChannelMessage::reply() - can't reply oneway message!" ); return; } if ( m_inEventHandler ) { m_replied = true; 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 @@ -39,128 +39,130 @@ namespace ThreadUtil { friend class WaitCondition; public: Mutex(); ~Mutex(); void lock(); void unlock(); bool tryLock(); bool isLocked(); private: struct Data; Data *d; Mutex( const Mutex & ); Mutex &operator=( const Mutex & ); }; class AutoLock { public: AutoLock( Mutex &mutex ) : m_mutex( mutex ) { m_mutex.lock(); } ~AutoLock() { m_mutex.unlock(); } Mutex *operator &() const { return &m_mutex; } private: Mutex &m_mutex; }; class WaitCondition { public: WaitCondition(); ~WaitCondition(); bool wait(); bool wait( Mutex &mutex ); void wakeOne(); void wakeAll(); private: struct Data; Data *d; WaitCondition( const WaitCondition & ); WaitCondition &operator=( const WaitCondition & ); }; class Thread { friend void *::_threadutil_start_thread( void* ); friend void ::_threadutil_terminate_thread( void* ); public: Thread(); virtual ~Thread(); void start(); void terminate(); bool wait(); + bool isRunning() const; + static void exit(); protected: virtual void run() = 0; private: struct Data; Data *d; }; class OnewayNotifier : public QObject { Q_OBJECT public: OnewayNotifier(); ~OnewayNotifier(); void notify(); signals: void awake(); private slots: void wakeUp(); private: int m_readFd; int m_writeFd; QSocketNotifier *m_notifier; }; class Channel; class ChannelMessage { friend class Channel; public: ChannelMessage( int type = -1 ); virtual ~ChannelMessage(); int type() const { return m_type; } void reply(); private: ChannelMessage( const ChannelMessage & ); ChannelMessage &operator=( const ChannelMessage ); int m_type; bool m_isCall : 1; bool m_replied : 1; bool m_inEventHandler : 1; Mutex m_guard; WaitCondition m_condition; QGuardedPtr<Channel> m_channel; }; class Channel : public QObject { Q_OBJECT public: enum SendType { OneWay, WaitForReply }; Channel( QObject *parent = 0, const char *name = 0 ); virtual ~Channel(); |