diff options
| author | 2021-06-20 01:56:35 +0200 | |
|---|---|---|
| committer | 2021-06-20 01:56:35 +0200 | |
| commit | cb50087482cf5a4239ad9c96b7157c45eac12876 (patch) | |
| tree | 1d60de827e4d9c08d7f51f16480d4583ee45ad25 /src | |
| parent | eb787a10f06e4470134cff33a81bb872e4268bfa (diff) | |
| download | libirecovery-cb50087482cf5a4239ad9c96b7157c45eac12876.tar.gz libirecovery-cb50087482cf5a4239ad9c96b7157c45eac12876.tar.bz2 | |
thread: Add condition variable support
Diffstat (limited to 'src')
| -rw-r--r-- | src/thread.c | 75 | ||||
| -rw-r--r-- | src/thread.h | 11 |
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 | ||
| 68 | int thread_alive(THREAD_T thread) | 68 | int 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 | |||
| 144 | void 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 | |||
| 153 | void cond_destroy(cond_t* cond) | ||
| 154 | { | ||
| 155 | #ifdef WIN32 | ||
| 156 | CloseHandle(cond->sem); | ||
| 157 | #else | ||
| 158 | pthread_cond_destroy(cond); | ||
| 159 | #endif | ||
| 160 | } | ||
| 161 | |||
| 162 | int 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 | |||
| 175 | int 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 | |||
| 191 | int 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> |
| 29 | typedef HANDLE THREAD_T; | 29 | typedef HANDLE THREAD_T; |
| 30 | typedef CRITICAL_SECTION mutex_t; | 30 | typedef CRITICAL_SECTION mutex_t; |
| 31 | typedef struct { | ||
| 32 | HANDLE sem; | ||
| 33 | } cond_t; | ||
| 31 | typedef volatile struct { | 34 | typedef 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> | ||
| 41 | typedef pthread_t THREAD_T; | 45 | typedef pthread_t THREAD_T; |
| 42 | typedef pthread_mutex_t mutex_t; | 46 | typedef pthread_mutex_t mutex_t; |
| 47 | typedef pthread_cond_t cond_t; | ||
| 43 | typedef pthread_once_t thread_once_t; | 48 | typedef 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 | ||
| 74 | void thread_once(thread_once_t *once_control, void (*init_routine)(void)); | 79 | void thread_once(thread_once_t *once_control, void (*init_routine)(void)); |
| 75 | 80 | ||
| 81 | void cond_init(cond_t* cond); | ||
| 82 | void cond_destroy(cond_t* cond); | ||
| 83 | int cond_signal(cond_t* cond); | ||
| 84 | int cond_wait(cond_t* cond, mutex_t* mutex); | ||
| 85 | int cond_wait_timeout(cond_t* cond, mutex_t* mutex, unsigned int timeout_ms); | ||
| 86 | |||
| 76 | #endif | 87 | #endif |
