Index: third_party/libwebp/utils/thread.c |
diff --git a/third_party/libwebp/utils/thread.c b/third_party/libwebp/utils/thread.c |
index 264210ba2807e4da47eb5d18c04cf869d89b9784..93f7622797f05f6acc1126e8296c481d276e4047 100644 |
--- a/third_party/libwebp/utils/thread.c |
+++ b/third_party/libwebp/utils/thread.c |
@@ -23,11 +23,26 @@ |
#include <windows.h> |
typedef HANDLE pthread_t; |
typedef CRITICAL_SECTION pthread_mutex_t; |
+ |
+#if _WIN32_WINNT >= 0x0600 // Windows Vista / Server 2008 or greater |
+#define USE_WINDOWS_CONDITION_VARIABLE |
+typedef CONDITION_VARIABLE pthread_cond_t; |
+#else |
typedef struct { |
HANDLE waiting_sem_; |
HANDLE received_sem_; |
HANDLE signal_event_; |
} pthread_cond_t; |
+#endif // _WIN32_WINNT >= 0x600 |
+ |
+#ifndef WINAPI_FAMILY_PARTITION |
+#define WINAPI_PARTITION_DESKTOP 1 |
+#define WINAPI_FAMILY_PARTITION(x) x |
+#endif |
+ |
+#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) |
+#define USE_CREATE_THREAD |
+#endif |
#else // !_WIN32 |
@@ -52,15 +67,29 @@ struct WebPWorkerImpl { |
#define THREADFN unsigned int __stdcall |
#define THREAD_RETURN(val) (unsigned int)((DWORD_PTR)val) |
+#if _WIN32_WINNT >= 0x0501 // Windows XP or greater |
+#define WaitForSingleObject(obj, timeout) \ |
+ WaitForSingleObjectEx(obj, timeout, FALSE /*bAlertable*/) |
+#endif |
+ |
static int pthread_create(pthread_t* const thread, const void* attr, |
unsigned int (__stdcall *start)(void*), void* arg) { |
(void)attr; |
+#ifdef USE_CREATE_THREAD |
+ *thread = CreateThread(NULL, /* lpThreadAttributes */ |
+ 0, /* dwStackSize */ |
+ start, |
+ arg, |
+ 0, /* dwStackSize */ |
+ NULL); /* lpThreadId */ |
+#else |
*thread = (pthread_t)_beginthreadex(NULL, /* void *security */ |
0, /* unsigned stack_size */ |
start, |
arg, |
0, /* unsigned initflag */ |
NULL); /* unsigned *thrdaddr */ |
+#endif |
if (*thread == NULL) return 1; |
SetThreadPriority(*thread, THREAD_PRIORITY_ABOVE_NORMAL); |
return 0; |
@@ -75,7 +104,11 @@ static int pthread_join(pthread_t thread, void** value_ptr) { |
// Mutex |
static int pthread_mutex_init(pthread_mutex_t* const mutex, void* mutexattr) { |
(void)mutexattr; |
+#if _WIN32_WINNT >= 0x0600 // Windows Vista / Server 2008 or greater |
+ InitializeCriticalSectionEx(mutex, 0 /*dwSpinCount*/, 0 /*Flags*/); |
+#else |
InitializeCriticalSection(mutex); |
+#endif |
return 0; |
} |
@@ -97,14 +130,21 @@ static int pthread_mutex_destroy(pthread_mutex_t* const mutex) { |
// Condition |
static int pthread_cond_destroy(pthread_cond_t* const condition) { |
int ok = 1; |
+#ifdef USE_WINDOWS_CONDITION_VARIABLE |
+ (void)condition; |
+#else |
ok &= (CloseHandle(condition->waiting_sem_) != 0); |
ok &= (CloseHandle(condition->received_sem_) != 0); |
ok &= (CloseHandle(condition->signal_event_) != 0); |
+#endif |
return !ok; |
} |
static int pthread_cond_init(pthread_cond_t* const condition, void* cond_attr) { |
(void)cond_attr; |
+#ifdef USE_WINDOWS_CONDITION_VARIABLE |
+ InitializeConditionVariable(condition); |
+#else |
condition->waiting_sem_ = CreateSemaphore(NULL, 0, 1, NULL); |
condition->received_sem_ = CreateSemaphore(NULL, 0, 1, NULL); |
condition->signal_event_ = CreateEvent(NULL, FALSE, FALSE, NULL); |
@@ -114,11 +154,15 @@ static int pthread_cond_init(pthread_cond_t* const condition, void* cond_attr) { |
pthread_cond_destroy(condition); |
return 1; |
} |
+#endif |
return 0; |
} |
static int pthread_cond_signal(pthread_cond_t* const condition) { |
int ok = 1; |
+#ifdef USE_WINDOWS_CONDITION_VARIABLE |
+ WakeConditionVariable(condition); |
+#else |
if (WaitForSingleObject(condition->waiting_sem_, 0) == WAIT_OBJECT_0) { |
// a thread is waiting in pthread_cond_wait: allow it to be notified |
ok = SetEvent(condition->signal_event_); |
@@ -127,12 +171,16 @@ static int pthread_cond_signal(pthread_cond_t* const condition) { |
ok &= (WaitForSingleObject(condition->received_sem_, INFINITE) != |
WAIT_OBJECT_0); |
} |
+#endif |
return !ok; |
} |
static int pthread_cond_wait(pthread_cond_t* const condition, |
pthread_mutex_t* const mutex) { |
int ok; |
+#ifdef USE_WINDOWS_CONDITION_VARIABLE |
+ ok = SleepConditionVariableCS(condition, mutex, INFINITE); |
+#else |
// note that there is a consumer available so the signal isn't dropped in |
// pthread_cond_signal |
if (!ReleaseSemaphore(condition->waiting_sem_, 1, NULL)) |
@@ -143,6 +191,7 @@ static int pthread_cond_wait(pthread_cond_t* const condition, |
WAIT_OBJECT_0); |
ok &= ReleaseSemaphore(condition->received_sem_, 1, NULL); |
pthread_mutex_lock(mutex); |
+#endif |
return !ok; |
} |