stop update length timer when a movie was selected
[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         p->m_alive = 0;
11
12                 /* recover state */
13         if (!p->m_state.value())
14         {
15                 p->m_state.up();
16                 assert(p->m_state.value() == 1);
17         }
18
19         p->thread_finished();
20 }
21
22 void *eThread::wrapper(void *ptr)
23 {
24         eThread *p = (eThread*)ptr;
25         pthread_cleanup_push(thread_completed, (void*)p);
26         p->thread();
27         pthread_exit(0);
28         pthread_cleanup_pop(1);
29         return 0;
30 }
31
32 eThread::eThread()
33         : the_thread(0), m_alive(0)
34 {
35 }
36
37 int eThread::runAsync(int prio, int policy)
38 {
39         eDebug("before: %d", m_state.value());
40                 /* the thread might already run. */
41         if (sync())
42                 return -1;
43         
44         eDebug("after: %d", m_state.value());
45         assert(m_state.value() == 1); /* sync postconditions */
46         assert(!m_alive);
47         m_state.down();
48         
49         m_alive = 1;
50
51                 /* start thread. */
52         pthread_attr_t attr;
53         pthread_attr_init(&attr);
54         
55         if (prio || policy)
56         {
57                 struct sched_param p;
58                 p.__sched_priority=prio;
59                 pthread_attr_setschedpolicy(&attr, policy);
60                 pthread_attr_setschedparam(&attr, &p);
61         }
62         
63         if (pthread_create(&the_thread, &attr, wrapper, this))
64         {
65                 pthread_attr_destroy(&attr);
66                 m_alive = 0;
67                 eDebug("couldn't create new thread");
68                 return -1;
69         }
70         
71         pthread_attr_destroy(&attr);
72         return 0;
73 }                     
74
75 int eThread::run(int prio, int policy)
76 {
77         if (runAsync(prio, policy))
78                 return -1;
79         sync();
80         return 0;
81 }
82
83 eThread::~eThread()
84 {
85         kill();
86 }
87
88 int eThread::sync(void)
89 {
90         int res;
91         m_state.down(); /* this might block */
92         res = m_alive;
93         assert(m_state.value() == 0);
94         m_state.up();
95         return res; /* 0: thread is guaranteed not to run. 1: state unknown. */
96 }
97
98 void eThread::sendSignal(int sig)
99 {
100         if (m_alive)
101                 pthread_kill(the_thread, sig);
102         else
103                 eDebug("send signal to non running thread");
104 }
105
106 void eThread::kill(bool sendcancel)
107 {
108         if (!the_thread) /* already joined */
109                 return;
110
111         if (sync() && sendcancel)
112         {
113                 eDebug("send cancel to thread");
114                 pthread_cancel(the_thread);
115         }
116         eDebug("thread joined %d", pthread_join(the_thread, 0));
117         the_thread = 0;
118 }
119
120 void eThread::hasStarted()
121 {
122         assert(!m_state.value());
123         m_state.up();
124 }