blob: 05056290c258b08070d9dd6e8da734fc3da22e9d
1 | /* |
2 | reference android api, just linux pthread |
3 | */ |
4 | |
5 | #ifndef _TV_UTILS_CONDITION_H |
6 | #define _TV_UTILS_CONDITION_H |
7 | |
8 | #include <stdint.h> |
9 | #include <sys/types.h> |
10 | #include <time.h> |
11 | #include <pthread.h> |
12 | #include "CMutex.h" |
13 | |
14 | typedef long long nsecs_t; |
15 | |
16 | class CCondition { |
17 | public: |
18 | enum { |
19 | PRIVATE = 0, |
20 | SHARED = 1 |
21 | }; |
22 | |
23 | CCondition(); |
24 | CCondition(int type); |
25 | ~CCondition(); |
26 | // Wait on the condition variable. Lock the mutex before calling. |
27 | int wait(CMutex &mutex); |
28 | // same with relative timeout |
29 | int waitRelative(CMutex &mutex, long sec); |
30 | // Signal the condition variable, allowing one thread to continue. |
31 | void signal(); |
32 | // Signal the condition variable, allowing all threads to continue. |
33 | void broadcast(); |
34 | |
35 | private: |
36 | pthread_cond_t mCond; |
37 | }; |
38 | |
39 | |
40 | |
41 | // --------------------------------------------------------------------------- |
42 | |
43 | inline CCondition::CCondition() |
44 | { |
45 | pthread_cond_init(&mCond, NULL); |
46 | } |
47 | inline CCondition::CCondition(int type) |
48 | { |
49 | if (type == SHARED) { |
50 | pthread_condattr_t attr; |
51 | pthread_condattr_init(&attr); |
52 | pthread_condattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); |
53 | pthread_cond_init(&mCond, &attr); |
54 | pthread_condattr_destroy(&attr); |
55 | } else { |
56 | pthread_cond_init(&mCond, NULL); |
57 | } |
58 | } |
59 | inline CCondition::~CCondition() |
60 | { |
61 | pthread_cond_destroy(&mCond); |
62 | } |
63 | inline int CCondition::wait(CMutex &mutex) |
64 | { |
65 | return -pthread_cond_wait(&mCond, &mutex.mMutex); |
66 | } |
67 | inline int CCondition::waitRelative(CMutex &mutex, long msec) |
68 | { |
69 | struct timespec ts; |
70 | long _nanoSec = 1000000000; |
71 | int _sec = msec / 1000; |
72 | long _nsec = (msec - 1000 * _sec) * 1000000; |
73 | clock_gettime(CLOCK_REALTIME, &ts); |
74 | ts.tv_sec += _sec; |
75 | ts.tv_nsec += _nsec; |
76 | if (ts.tv_nsec > _nanoSec) { |
77 | ts.tv_nsec %= _nanoSec; |
78 | ts.tv_sec++; |
79 | } |
80 | return -pthread_cond_timedwait(&mCond, &mutex.mMutex, &ts); |
81 | } |
82 | inline void CCondition::signal() |
83 | { |
84 | pthread_cond_signal(&mCond); |
85 | } |
86 | inline void CCondition::broadcast() |
87 | { |
88 | pthread_cond_broadcast(&mCond); |
89 | } |
90 | #endif |
91 |