summaryrefslogtreecommitdiff
path: root/graphtft-fe/thread.h
diff options
context:
space:
mode:
Diffstat (limited to 'graphtft-fe/thread.h')
-rw-r--r--graphtft-fe/thread.h160
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