Mercurial > hg > qm-dsp
diff thread/Thread.h @ 62:b63f1ccbc9b6
* oops... add thread abstraction
author | cannam |
---|---|
date | Tue, 12 May 2009 17:56:58 +0000 |
parents | |
children | 0dcbce5d7dce |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/thread/Thread.h Tue May 12 17:56:58 2009 +0000 @@ -0,0 +1,144 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + QM DSP Library + + Centre for Digital Music, Queen Mary, University of London. + This file copyright Chris Cannam, used with permission. +*/ + +#ifndef _THREAD_H_ +#define _THREAD_H_ + +#ifdef _WIN32 +#include <windows.h> +#else /* !_WIN32 */ +#ifdef USE_PTHREADS +#include <pthread.h> +#endif /* USE_PTHREADS */ +#endif /* !_WIN32 */ + +#include <string> + +//#define DEBUG_THREAD 1 +//#define DEBUG_MUTEX 1 +//#define DEBUG_CONDITION 1 + +class Thread +{ +public: +#ifdef _WIN32 + typedef HANDLE Id; +#else +#ifdef USE_PTHREADS + typedef pthread_t Id; +#endif +#endif + + Thread(); + virtual ~Thread(); + + Id id(); + + void start(); + void wait(); + + static bool threadingAvailable(); + +protected: + virtual void run() = 0; + +private: +#ifdef _WIN32 + HANDLE m_id; + bool m_extant; + static DWORD WINAPI staticRun(LPVOID lpParam); +#else +#ifdef USE_PTHREADS + pthread_t m_id; + bool m_extant; + static void *staticRun(void *); +#endif +#endif +}; + +class Mutex +{ +public: + Mutex(); + ~Mutex(); + + void lock(); + void unlock(); + bool trylock(); + +private: +#ifdef _WIN32 + HANDLE m_mutex; +#ifndef NO_THREAD_CHECKS + DWORD m_lockedBy; +#endif +#else +#ifdef USE_PTHREADS + pthread_mutex_t m_mutex; +#ifndef NO_THREAD_CHECKS + pthread_t m_lockedBy; + bool m_locked; +#endif +#endif +#endif +}; + +class MutexLocker +{ +public: + MutexLocker(Mutex *); + ~MutexLocker(); + +private: + Mutex *m_mutex; +}; + +class Condition +{ +public: + Condition(std::string name); + ~Condition(); + + //!!! NO -- reproducing more conventional lock/wait + + // To wait on a condition, either simply call wait(), or call + // lock() and then wait() (perhaps testing some state in between). + // To signal a condition, call signal(). + + // Although any thread may signal on a given condition, only one + // thread should ever wait on any given condition object -- + // otherwise there will be a race conditions in the logic that + // avoids the thread code having to track whether the condition's + // mutex is locked or not. If that is your requirement, this + // Condition wrapper is not for you. + void lock(); + void unlock(); + void wait(int us = 0); + + void signal(); + +private: + +#ifdef _WIN32 + HANDLE m_mutex; + HANDLE m_condition; + bool m_locked; +#else +#ifdef USE_PTHREADS + pthread_mutex_t m_mutex; + pthread_cond_t m_condition; + bool m_locked; +#endif +#endif +#ifdef DEBUG_CONDITION + std::string m_name; +#endif +}; + +#endif