diff options
Diffstat (limited to 'graphtft-fe/thread.h')
-rw-r--r-- | graphtft-fe/thread.h | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/graphtft-fe/thread.h b/graphtft-fe/thread.h new file mode 100644 index 0000000..e40d222 --- /dev/null +++ b/graphtft-fe/thread.h @@ -0,0 +1,160 @@ +/* + * thread.h: A simple thread base class + * + * See the main source file 'vdr.c' for copyright information and + * how to reach the author. + * + * $Id: thread.h 2.0 2007/02/24 16:13:28 kls Exp $ + */ + +#ifndef __MYTHREAD_H +#define __MYTHREAD_H + +#include <pthread.h> +#include <stdio.h> +#include <sys/types.h> + +class cCondWait +{ + private: + pthread_mutex_t mutex; + pthread_cond_t cond; + bool signaled; + public: + cCondWait(void); + ~cCondWait(); + static void SleepMs(int TimeoutMs); + ///< Creates a cCondWait object and uses it to sleep for TimeoutMs + ///< milliseconds, immediately giving up the calling thread's time + ///< slice and thus avoiding a "busy wait". + ///< In order to avoid a possible busy wait, TimeoutMs will be automatically + ///< limited to values >2. + bool Wait(int TimeoutMs = 0); + ///< Waits at most TimeoutMs milliseconds for a call to Signal(), or + ///< forever if TimeoutMs is 0. + ///< \return Returns true if Signal() has been called, false it the given + ///< timeout has expired. + void Signal(void); + ///< Signals a caller of Wait() that the condition it is waiting for is met. +}; + +class cMutex; + +class cCondVar { +private: + pthread_cond_t cond; +public: + cCondVar(void); + ~cCondVar(); + void Wait(cMutex &Mutex); + bool TimedWait(cMutex &Mutex, int TimeoutMs); + void Broadcast(void); + }; + +class cRwLock { +private: + pthread_rwlock_t rwlock; +public: + cRwLock(bool PreferWriter = false); + ~cRwLock(); + bool Lock(bool Write, int TimeoutMs = 0); + void Unlock(void); + }; + +class cMutex { + friend class cCondVar; +private: + pthread_mutex_t mutex; + int locked; +public: + cMutex(void); + ~cMutex(); + void Lock(void); + void Unlock(void); + }; + +typedef pid_t tThreadId; + +class cMyThread { + friend class cMyThreadLock; +private: + bool active; + bool running; + pthread_t childTid; + tThreadId childThreadId; + cMutex mutex; + char *description; + static tThreadId mainThreadId; + static void *StartThread(cMyThread *Thread); +protected: + void SetPriority(int Priority); + void Lock(void) { mutex.Lock(); } + void Unlock(void) { mutex.Unlock(); } + virtual void Action(void) = 0; + ///< A derived cMyThread class must implement the code it wants to + ///< execute as a separate thread in this function. If this is + ///< a loop, it must check Running() repeatedly to see whether + ///< it's time to stop. + bool Running(void) { return running; } + ///< Returns false if a derived cMyThread object shall leave its Action() + ///< function. + void Cancel(int WaitSeconds = 0); + ///< Cancels the thread by first setting 'running' to false, so that + ///< the Action() loop can finish in an orderly fashion and then waiting + ///< up to WaitSeconds seconds for the thread to actually end. If the + ///< thread doesn't end by itself, it is killed. + ///< If WaitSeconds is -1, only 'running' is set to false and Cancel() + ///< returns immediately, without killing the thread. +public: + cMyThread(const char *Description = NULL); + ///< Creates a new thread. + ///< If Description is present, a log file entry will be made when + ///< the thread starts and stops. The Start() function must be called + ///< to actually start the thread. + virtual ~cMyThread(); + void SetDescription(const char *Description); + bool Start(void); + ///< Actually starts the thread. + ///< If the thread is already running, nothing happens. + bool Active(void); + ///< Checks whether the thread is still alive. + static tThreadId ThreadId(void); + static tThreadId IsMainThread(void) { return ThreadId() == mainThreadId; } + static void SetMainThreadId(void); + }; + +// cMutexLock can be used to easily set a lock on mutex and make absolutely +// sure that it will be unlocked when the block will be left. Several locks can +// be stacked, so a function that makes many calls to another function which uses +// cMutexLock may itself use a cMutexLock to make one longer lock instead of many +// short ones. + +class cMutexLock { +private: + cMutex *mutex; + bool locked; +public: + cMutexLock(cMutex *Mutex = NULL); + ~cMutexLock(); + bool Lock(cMutex *Mutex); + }; + +// cMyThreadLock can be used to easily set a lock in a thread and make absolutely +// sure that it will be unlocked when the block will be left. Several locks can +// be stacked, so a function that makes many calls to another function which uses +// cMyThreadLock may itself use a cMyThreadLock to make one longer lock instead of many +// short ones. + +class cMyThreadLock { +private: + cMyThread *thread; + bool locked; +public: + cMyThreadLock(cMyThread *Thread = NULL); + ~cMyThreadLock(); + bool Lock(cMyThread *Thread); + }; + +//#define LOCK_THREAD cMyThreadLock ThreadLock(this) + +#endif //__MYTHREAD_H |