try to fix some eThread races
[enigma2.git] / lib / base / thread.h
index 94cdd47..dad8042 100644 (file)
@@ -3,26 +3,63 @@
 
 #include <pthread.h>
 #include <signal.h>
+#include <lib/base/elock.h>
+
+/* the following states are possible:
+ 1 thread has not yet started
+ 2 thread has started, but not completed initialization (hadStarted not yet called)
+ 3 thread is running
+ 4 thread has finished, but not yet joined
+ 5 thread has joined (same as state 1)
+ sync() will return:
+       0 (="not alive") for 1, 4, 5
+       1 for 3, 4
+       
+       it will wait when state is 2. It can't differentiate between
+       state 3 and 4, because a thread could always finish.
+       
+       all other state transitions (1 -> 2, 4 -> 5) must be activately
+       changed by either calling run() or kill().
+ */
 
 class eThread
 {
-       pthread_t the_thread;
-       static void *wrapper(void *ptr);
-       int alive;
-       static void thread_completed(void *p);
 public:
-       bool thread_running() { return alive; }
        eThread();
        virtual ~eThread();
 
-       void run(int prio=0, int policy=0);
+               /* runAsync starts the thread.
+                  it assumes that the thread is not running,
+                  i.e. sync() *must* return 0.
+                  it will not wait for anything. */
+       int runAsync(int prio=0, int policy=0);
+
+               /* run will wait until the thread has either
+                  passed it's initialization, or it has
+                  died again. */
+       int run(int prio=0, int policy=0);
 
        virtual void thread()=0;
-       virtual void before_set_thread_alive() { }
-       virtual void thread_finished() { }
+       
+               /* waits until thread is in "run" state */
+               /* result: 0 - thread is not alive
+                          1 - thread state unknown */
+       int sync();
        void sendSignal(int sig);
 
+               /* join the thread, i.e. busywait until thread has finnished. */
        void kill(bool sendcancel=false);
+private:
+       pthread_t the_thread;
+
+       static void *wrapper(void *ptr);
+       int m_alive;
+       static void thread_completed(void *p);
+
+       eSemaphore m_state;
+protected:
+       void hasStarted();
 };
 
 #endif