improve locking of addTimeOffset a bit
[enigma2.git] / lib / base / thread.cpp
1 #include <lib/base/thread.h>
2
3 #include <stdio.h>
4 #include <unistd.h>
5 #include <lib/base/eerror.h>
6
7 void eThread::thread_completed(void *ptr)
8 {
9         eThread *p = (eThread*) ptr;
10         eDebug("thread has completed..");
11         p->alive=0;
12         p->thread_finished();
13 }
14
15 void *eThread::wrapper(void *ptr)
16 {
17         eThread *p = (eThread*)ptr;
18         p->alive=1;
19         pthread_cleanup_push( thread_completed, (void*)p );
20         p->thread();
21         pthread_exit(0);
22         pthread_cleanup_pop(0);
23         return 0;
24 }
25
26 eThread::eThread()
27         :the_thread(0), alive(0)
28 {
29 }
30
31 void eThread::run( int prio, int policy )
32 {
33         if (alive)
34         {
35                 eDebug("thread already running !!");
36                 return;
37         }
38         pthread_attr_t attr;
39         pthread_attr_init(&attr);
40         if (prio||policy)
41         {
42                 struct sched_param p;
43                 p.__sched_priority=prio;
44                 pthread_attr_setschedpolicy(&attr, policy );
45                 pthread_attr_setschedparam(&attr, &p);
46         }
47         if ( pthread_create(&the_thread, &attr, wrapper, this) )
48         {
49                 eDebug("couldn't create new thread");
50                 return;
51         }
52         pthread_attr_destroy(&attr);
53         usleep(1000);
54         int timeout=20;
55         while(!alive && timeout--)
56         {
57                 eDebug("waiting for thread start...");
58                 usleep(1000*10);
59         }
60         if ( !timeout )
61                 eDebug("thread couldn't be started !!!");
62 }                     
63
64 eThread::~eThread()
65 {
66         kill();
67 }
68
69 void eThread::sendSignal(int sig)
70 {
71         if ( alive )
72                 pthread_kill( the_thread, sig );
73         else
74                 eDebug("send signal to non running thread");
75 }
76
77 void eThread::kill(bool sendcancel)
78 {
79         if (!the_thread)
80                 return;
81         if ( alive && sendcancel )
82         {
83                 eDebug("send cancel to thread");
84                 pthread_cancel(the_thread);
85         }
86         eDebug("thread joined %d", pthread_join(the_thread, 0));
87         the_thread=0;
88 }