Support pthread_cond_* on Win32
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
diff --git a/src/win32/pthread.c b/src/win32/pthread.c
index 3a186c8..cbed9d9 100644
--- a/src/win32/pthread.c
+++ b/src/win32/pthread.c
@@ -54,6 +54,71 @@ int pthread_mutex_unlock(pthread_mutex_t *mutex)
return 0;
}
+int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
+{
+ /* We don't support non-default attributes. */
+ if (attr)
+ return EINVAL;
+
+ /* This is an auto-reset event. */
+ *cond = CreateEventW(NULL, FALSE, FALSE, NULL);
+ assert(*cond);
+
+ /* If we can't create the event, claim that the reason was out-of-memory.
+ * The actual reason can be fetched with GetLastError(). */
+ return *cond ? 0 : ENOMEM;
+}
+
+int pthread_cond_destroy(pthread_cond_t *cond)
+{
+ BOOL closed;
+
+ if (!cond)
+ return EINVAL;
+
+ closed = CloseHandle(*cond);
+ assert(closed);
+
+ *cond = NULL;
+ return 0;
+}
+
+int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
+{
+ int error;
+ DWORD wait_result;
+
+ if (!cond || !mutex)
+ return EINVAL;
+
+ /* The caller must be holding the mutex. */
+ error = pthread_mutex_unlock(mutex);
+
+ if (error)
+ return error;
+
+ wait_result = WaitForSingleObject(*cond, INFINITE);
+ assert(WAIT_OBJECT_0 == wait_result);
+
+ return pthread_mutex_lock(mutex);
+}
+
+int pthread_cond_signal(pthread_cond_t *cond)
+{
+ BOOL signaled;
+
+ if (!cond)
+ return EINVAL;
+
+ signaled = SetEvent(*cond);
+ assert(signaled);
+
+ return 0;
+}
+
+/* pthread_cond_broadcast is not implemented because doing so with just Win32 events
+ * is quite complicated, and no caller in libgit2 uses it yet. */
+
int pthread_num_processors_np(void)
{
DWORD_PTR p, s;
diff --git a/src/win32/pthread.h b/src/win32/pthread.h
index b194cbf..136f9b1 100644
--- a/src/win32/pthread.h
+++ b/src/win32/pthread.h
@@ -21,6 +21,7 @@ typedef int pthread_condattr_t;
typedef int pthread_attr_t;
typedef CRITICAL_SECTION pthread_mutex_t;
typedef HANDLE pthread_t;
+typedef HANDLE pthread_cond_t;
#define PTHREAD_MUTEX_INITIALIZER {(void*)-1};
@@ -35,6 +36,12 @@ int pthread_mutex_destroy(pthread_mutex_t *);
int pthread_mutex_lock(pthread_mutex_t *);
int pthread_mutex_unlock(pthread_mutex_t *);
+int pthread_cond_init(pthread_cond_t *, const pthread_condattr_t *);
+int pthread_cond_destroy(pthread_cond_t *);
+int pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *);
+int pthread_cond_signal(pthread_cond_t *);
+/* pthread_cond_broadcast is not supported on Win32 yet. */
+
int pthread_num_processors_np(void);
#endif