summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2021-06-20 01:56:35 +0200
committerGravatar Nikias Bassen2021-06-20 01:56:35 +0200
commitcb50087482cf5a4239ad9c96b7157c45eac12876 (patch)
tree1d60de827e4d9c08d7f51f16480d4583ee45ad25
parenteb787a10f06e4470134cff33a81bb872e4268bfa (diff)
downloadlibirecovery-cb50087482cf5a4239ad9c96b7157c45eac12876.tar.gz
libirecovery-cb50087482cf5a4239ad9c96b7157c45eac12876.tar.bz2
thread: Add condition variable support
-rw-r--r--src/thread.c75
-rw-r--r--src/thread.h11
2 files changed, 86 insertions, 0 deletions
diff --git a/src/thread.c b/src/thread.c
index eb535ab..796ea0b 100644
--- a/src/thread.c
+++ b/src/thread.c
@@ -67,6 +67,8 @@ int thread_join(THREAD_T thread)
67 67
68int thread_alive(THREAD_T thread) 68int thread_alive(THREAD_T thread)
69{ 69{
70 if (!thread)
71 return 0;
70#ifdef WIN32 72#ifdef WIN32
71 return WaitForSingleObject(thread, 0) == WAIT_TIMEOUT; 73 return WaitForSingleObject(thread, 0) == WAIT_TIMEOUT;
72#else 74#else
@@ -138,3 +140,76 @@ void thread_once(thread_once_t *once_control, void (*init_routine)(void))
138 pthread_once(once_control, init_routine); 140 pthread_once(once_control, init_routine);
139#endif 141#endif
140} 142}
143
144void cond_init(cond_t* cond)
145{
146#ifdef WIN32
147 cond->sem = CreateSemaphore(NULL, 0, 32767, NULL);
148#else
149 pthread_cond_init(cond, NULL);
150#endif
151}
152
153void cond_destroy(cond_t* cond)
154{
155#ifdef WIN32
156 CloseHandle(cond->sem);
157#else
158 pthread_cond_destroy(cond);
159#endif
160}
161
162int cond_signal(cond_t* cond)
163{
164#ifdef WIN32
165 int result = 0;
166 if (!ReleaseSemaphore(cond->sem, 1, NULL)) {
167 result = -1;
168 }
169 return result;
170#else
171 return pthread_cond_signal(cond);
172#endif
173}
174
175int cond_wait(cond_t* cond, mutex_t* mutex)
176{
177#ifdef WIN32
178 mutex_unlock(mutex);
179 DWORD res = WaitForSingleObject(cond->sem, INFINITE);
180 switch (res) {
181 case WAIT_OBJECT_0:
182 return 0;
183 default:
184 return -1;
185 }
186#else
187 return pthread_cond_wait(cond, mutex);
188#endif
189}
190
191int cond_wait_timeout(cond_t* cond, mutex_t* mutex, unsigned int timeout_ms)
192{
193#ifdef WIN32
194 mutex_unlock(mutex);
195 DWORD res = WaitForSingleObject(cond->sem, timeout_ms);
196 switch (res) {
197 case WAIT_OBJECT_0:
198 case WAIT_TIMEOUT:
199 return 0;
200 default:
201 return -1;
202 }
203#else
204 struct timespec ts;
205 struct timeval now;
206 gettimeofday(&now, NULL);
207
208 ts.tv_sec = now.tv_sec + timeout_ms / 1000;
209 ts.tv_nsec = now.tv_usec * 1000 + 1000 * 1000 * (timeout_ms % 1000);
210 ts.tv_sec += ts.tv_nsec / (1000 * 1000 * 1000);
211 ts.tv_nsec %= (1000 * 1000 * 1000);
212
213 return pthread_cond_timedwait(cond, mutex, &ts);
214#endif
215}
diff --git a/src/thread.h b/src/thread.h
index 23e4510..2aadc6e 100644
--- a/src/thread.h
+++ b/src/thread.h
@@ -28,6 +28,9 @@
28#include <windows.h> 28#include <windows.h>
29typedef HANDLE THREAD_T; 29typedef HANDLE THREAD_T;
30typedef CRITICAL_SECTION mutex_t; 30typedef CRITICAL_SECTION mutex_t;
31typedef struct {
32 HANDLE sem;
33} cond_t;
31typedef volatile struct { 34typedef volatile struct {
32 LONG lock; 35 LONG lock;
33 int state; 36 int state;
@@ -38,8 +41,10 @@ typedef volatile struct {
38#else 41#else
39#include <pthread.h> 42#include <pthread.h>
40#include <signal.h> 43#include <signal.h>
44#include <sys/time.h>
41typedef pthread_t THREAD_T; 45typedef pthread_t THREAD_T;
42typedef pthread_mutex_t mutex_t; 46typedef pthread_mutex_t mutex_t;
47typedef pthread_cond_t cond_t;
43typedef pthread_once_t thread_once_t; 48typedef pthread_once_t thread_once_t;
44#define THREAD_ONCE_INIT PTHREAD_ONCE_INIT 49#define THREAD_ONCE_INIT PTHREAD_ONCE_INIT
45#define THREAD_ID pthread_self() 50#define THREAD_ID pthread_self()
@@ -73,4 +78,10 @@ void mutex_unlock(mutex_t* mutex);
73 78
74void thread_once(thread_once_t *once_control, void (*init_routine)(void)); 79void thread_once(thread_once_t *once_control, void (*init_routine)(void));
75 80
81void cond_init(cond_t* cond);
82void cond_destroy(cond_t* cond);
83int cond_signal(cond_t* cond);
84int cond_wait(cond_t* cond, mutex_t* mutex);
85int cond_wait_timeout(cond_t* cond, mutex_t* mutex, unsigned int timeout_ms);
86
76#endif 87#endif