|
|
@@ -0,0 +1,81 @@
|
|
|
+#include "toolkit.h"
|
|
|
+#include "assert.h"
|
|
|
+
|
|
|
+#ifdef _WIN32
|
|
|
+
|
|
|
+int toolkit_mutex_init(toolkit_mutex_t* mutex) {
|
|
|
+ InitializeCriticalSection(mutex);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+int toolkit_mutex_init_recursive(toolkit_mutex_t* mutex) {
|
|
|
+ return toolkit_mutex_init(mutex);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+void toolkit_mutex_destroy(toolkit_mutex_t* mutex) {
|
|
|
+ DeleteCriticalSection(mutex);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+void toolkit_mutex_lock(toolkit_mutex_t* mutex) {
|
|
|
+ EnterCriticalSection(mutex);
|
|
|
+}
|
|
|
+
|
|
|
+int toolkit_mutex_trylock(toolkit_mutex_t* mutex) {
|
|
|
+ if (TryEnterCriticalSection(mutex))
|
|
|
+ return 0;
|
|
|
+ else
|
|
|
+ return -1;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+void toolkit_mutex_unlock(toolkit_mutex_t* mutex) {
|
|
|
+ LeaveCriticalSection(mutex);
|
|
|
+}
|
|
|
+
|
|
|
+static void toolkit__once_inner(toolkit_once_t* guard, void (*callback)(void))
|
|
|
+{
|
|
|
+ DWORD result;
|
|
|
+ HANDLE existing_event, created_event;
|
|
|
+
|
|
|
+ created_event = CreateEvent(NULL, 1, 0, NULL);
|
|
|
+ if (created_event == 0) {
|
|
|
+ /* Could fail in a low-memory situation? */
|
|
|
+ abort();
|
|
|
+ }
|
|
|
+
|
|
|
+ existing_event = InterlockedCompareExchangePointer(&guard->event,
|
|
|
+ created_event,
|
|
|
+ NULL);
|
|
|
+
|
|
|
+ if (existing_event == NULL) {
|
|
|
+ /* We won the race */
|
|
|
+ callback();
|
|
|
+
|
|
|
+ result = SetEvent(created_event);
|
|
|
+ assert(result);
|
|
|
+ guard->ran = 1;
|
|
|
+
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ /* We lost the race. Destroy the event we created and wait for the existing
|
|
|
+ * one to become signaled. */
|
|
|
+ CloseHandle(created_event);
|
|
|
+ result = WaitForSingleObject(existing_event, INFINITE);
|
|
|
+ assert(result == WAIT_OBJECT_0);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+void toolkit_once(toolkit_once_t* guard, void (*callback)(void))
|
|
|
+{
|
|
|
+ /* Fast case - avoid WaitForSingleObject. */
|
|
|
+ if (guard->ran) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ toolkit__once_inner(guard, callback);
|
|
|
+}
|
|
|
+
|
|
|
+#endif //_WIN32
|