aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/utils
diff options
context:
space:
mode:
authorGravatar mtklein <mtklein@chromium.org>2014-11-03 17:25:54 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2014-11-03 17:25:54 -0800
commitdb8d0e5bb018594d0ced3bfa68484115d8cf76b8 (patch)
tree09f0a060d6e28107715e4800e8da440359ba1d41 /src/utils
parent7c11aadd8268a1b003771ebb2aa82d53a909fe86 (diff)
Manually load CONDITION_VARIABLE methods on Windows, checking for failure (XP).
Tested by running DM on XP. Before this patch, it fails at startup (even just out/Debug/dm --help). Now it asserts for other reasons later on in user code, which is just fine by me. The net effect is that SkTaskGroups will always be synchronous on XP. That's not ideal, but a step up from crashing. CQ_EXTRA_TRYBOTS=client.skia:Test-Win7-ShuttleA-HD2000-x86-Release-Trybot,Test-Win7-ShuttleA-HD2000-x86_64-Release-Trybot BUG=skia: Review URL: https://codereview.chromium.org/700683002
Diffstat (limited to 'src/utils')
-rw-r--r--src/utils/SkCondVar.cpp45
-rw-r--r--src/utils/SkCondVar.h20
2 files changed, 50 insertions, 15 deletions
diff --git a/src/utils/SkCondVar.cpp b/src/utils/SkCondVar.cpp
index 5d001c0edd..ce5ef3e2eb 100644
--- a/src/utils/SkCondVar.cpp
+++ b/src/utils/SkCondVar.cpp
@@ -7,13 +7,47 @@
#include "SkCondVar.h"
+#if defined(SK_BUILD_FOR_WIN32)
+ static void (WINAPI *initialize_condition_variable)(PCONDITION_VARIABLE);
+ static BOOL (WINAPI *sleep_condition_variable)(PCONDITION_VARIABLE, PCRITICAL_SECTION, DWORD);
+ static void (WINAPI *wake_condition_variable)(PCONDITION_VARIABLE);
+ static void (WINAPI *wake_all_condition_variable)(PCONDITION_VARIABLE);
+
+ template <typename T>
+ static void set_fn_ptr(T* ptr, FARPROC fn) { *ptr = reinterpret_cast<T>(fn); }
+#endif
+
+bool SkCondVar::Supported() {
+#ifdef SK_USE_POSIX_THREADS
+ return true;
+#elif defined(SK_BUILD_FOR_WIN32)
+ // If we're >= Vista we'll find these functions. Otherwise (XP) SkCondVar is not supported.
+ HMODULE kernel32 = GetModuleHandleA("kernel32.dll");
+ set_fn_ptr(&initialize_condition_variable,
+ GetProcAddress(kernel32, "InitializeConditionVariable"));
+ set_fn_ptr(&sleep_condition_variable,
+ GetProcAddress(kernel32, "SleepConditionVariableCS"));
+ set_fn_ptr(&wake_condition_variable,
+ GetProcAddress(kernel32, "WakeConditionVariable"));
+ set_fn_ptr(&wake_all_condition_variable,
+ GetProcAddress(kernel32, "WakeAllConditionVariable"));
+ return initialize_condition_variable
+ && sleep_condition_variable
+ && wake_condition_variable
+ && wake_all_condition_variable;
+#else
+ return false;
+#endif
+}
+
SkCondVar::SkCondVar() {
#ifdef SK_USE_POSIX_THREADS
pthread_mutex_init(&fMutex, NULL /* default mutex attr */);
pthread_cond_init(&fCond, NULL /* default cond attr */);
#elif defined(SK_BUILD_FOR_WIN32)
InitializeCriticalSection(&fCriticalSection);
- InitializeConditionVariable(&fCondition);
+ SkASSERT(initialize_condition_variable);
+ initialize_condition_variable(&fCondition);
#endif
}
@@ -47,7 +81,8 @@ void SkCondVar::wait() {
#ifdef SK_USE_POSIX_THREADS
pthread_cond_wait(&fCond, &fMutex);
#elif defined(SK_BUILD_FOR_WIN32)
- SleepConditionVariableCS(&fCondition, &fCriticalSection, INFINITE);
+ SkASSERT(sleep_condition_variable);
+ sleep_condition_variable(&fCondition, &fCriticalSection, INFINITE);
#endif
}
@@ -55,7 +90,8 @@ void SkCondVar::signal() {
#ifdef SK_USE_POSIX_THREADS
pthread_cond_signal(&fCond);
#elif defined(SK_BUILD_FOR_WIN32)
- WakeConditionVariable(&fCondition);
+ SkASSERT(wake_condition_variable);
+ wake_condition_variable(&fCondition);
#endif
}
@@ -63,6 +99,7 @@ void SkCondVar::broadcast() {
#ifdef SK_USE_POSIX_THREADS
pthread_cond_broadcast(&fCond);
#elif defined(SK_BUILD_FOR_WIN32)
- WakeAllConditionVariable(&fCondition);
+ SkASSERT(wake_all_condition_variable);
+ wake_all_condition_variable(&fCondition);
#endif
}
diff --git a/src/utils/SkCondVar.h b/src/utils/SkCondVar.h
index 6f18e1a651..7f4225c66a 100644
--- a/src/utils/SkCondVar.h
+++ b/src/utils/SkCondVar.h
@@ -8,31 +8,29 @@
#ifndef SkCondVar_DEFINED
#define SkCondVar_DEFINED
-/**
- * Import any thread model setting from configuration files.
- */
#include "SkTypes.h"
#ifdef SK_USE_POSIX_THREADS
-#include <pthread.h>
+ #include <pthread.h>
#elif defined(SK_BUILD_FOR_WIN32)
-#include <windows.h>
+ #include <windows.h>
#else
-/**
- * Warn if the implementation of this class is empty, i.e. thread safety is not working.
- */
-#warning "Thread safety class SkCondVar has no implementation!"
+ #error "SkCondVar requires pthreads or Windows."
#endif
/**
* Condition variable for blocking access to shared data from other threads and
* controlling which threads are awake.
*
- * Currently only supported on platforms with posix threads and Windows Vista and
- * above.
+ * Currently only supported on platforms with posix threads and Windows Vista and above.
*/
class SkCondVar {
public:
+ /** Returns true if it makes sense to create and use SkCondVars.
+ * You _MUST_ call this method and it must return true before creating any SkCondVars.
+ */
+ static bool Supported();
+
SkCondVar();
~SkCondVar();