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
This commit is contained in:
parent
7c11aadd82
commit
db8d0e5bb0
@ -165,7 +165,7 @@ ThreadPool* ThreadPool::gGlobal = NULL;
|
|||||||
|
|
||||||
SkTaskGroup::Enabler::Enabler(int threads) {
|
SkTaskGroup::Enabler::Enabler(int threads) {
|
||||||
SkASSERT(ThreadPool::gGlobal == NULL);
|
SkASSERT(ThreadPool::gGlobal == NULL);
|
||||||
if (threads != 0) {
|
if (threads != 0 && SkCondVar::Supported()) {
|
||||||
ThreadPool::gGlobal = SkNEW_ARGS(ThreadPool, (threads));
|
ThreadPool::gGlobal = SkNEW_ARGS(ThreadPool, (threads));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,13 +7,47 @@
|
|||||||
|
|
||||||
#include "SkCondVar.h"
|
#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() {
|
SkCondVar::SkCondVar() {
|
||||||
#ifdef SK_USE_POSIX_THREADS
|
#ifdef SK_USE_POSIX_THREADS
|
||||||
pthread_mutex_init(&fMutex, NULL /* default mutex attr */);
|
pthread_mutex_init(&fMutex, NULL /* default mutex attr */);
|
||||||
pthread_cond_init(&fCond, NULL /* default cond attr */);
|
pthread_cond_init(&fCond, NULL /* default cond attr */);
|
||||||
#elif defined(SK_BUILD_FOR_WIN32)
|
#elif defined(SK_BUILD_FOR_WIN32)
|
||||||
InitializeCriticalSection(&fCriticalSection);
|
InitializeCriticalSection(&fCriticalSection);
|
||||||
InitializeConditionVariable(&fCondition);
|
SkASSERT(initialize_condition_variable);
|
||||||
|
initialize_condition_variable(&fCondition);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,7 +81,8 @@ void SkCondVar::wait() {
|
|||||||
#ifdef SK_USE_POSIX_THREADS
|
#ifdef SK_USE_POSIX_THREADS
|
||||||
pthread_cond_wait(&fCond, &fMutex);
|
pthread_cond_wait(&fCond, &fMutex);
|
||||||
#elif defined(SK_BUILD_FOR_WIN32)
|
#elif defined(SK_BUILD_FOR_WIN32)
|
||||||
SleepConditionVariableCS(&fCondition, &fCriticalSection, INFINITE);
|
SkASSERT(sleep_condition_variable);
|
||||||
|
sleep_condition_variable(&fCondition, &fCriticalSection, INFINITE);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,7 +90,8 @@ void SkCondVar::signal() {
|
|||||||
#ifdef SK_USE_POSIX_THREADS
|
#ifdef SK_USE_POSIX_THREADS
|
||||||
pthread_cond_signal(&fCond);
|
pthread_cond_signal(&fCond);
|
||||||
#elif defined(SK_BUILD_FOR_WIN32)
|
#elif defined(SK_BUILD_FOR_WIN32)
|
||||||
WakeConditionVariable(&fCondition);
|
SkASSERT(wake_condition_variable);
|
||||||
|
wake_condition_variable(&fCondition);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,6 +99,7 @@ void SkCondVar::broadcast() {
|
|||||||
#ifdef SK_USE_POSIX_THREADS
|
#ifdef SK_USE_POSIX_THREADS
|
||||||
pthread_cond_broadcast(&fCond);
|
pthread_cond_broadcast(&fCond);
|
||||||
#elif defined(SK_BUILD_FOR_WIN32)
|
#elif defined(SK_BUILD_FOR_WIN32)
|
||||||
WakeAllConditionVariable(&fCondition);
|
SkASSERT(wake_all_condition_variable);
|
||||||
|
wake_all_condition_variable(&fCondition);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -8,9 +8,6 @@
|
|||||||
#ifndef SkCondVar_DEFINED
|
#ifndef SkCondVar_DEFINED
|
||||||
#define SkCondVar_DEFINED
|
#define SkCondVar_DEFINED
|
||||||
|
|
||||||
/**
|
|
||||||
* Import any thread model setting from configuration files.
|
|
||||||
*/
|
|
||||||
#include "SkTypes.h"
|
#include "SkTypes.h"
|
||||||
|
|
||||||
#ifdef SK_USE_POSIX_THREADS
|
#ifdef SK_USE_POSIX_THREADS
|
||||||
@ -18,21 +15,22 @@
|
|||||||
#elif defined(SK_BUILD_FOR_WIN32)
|
#elif defined(SK_BUILD_FOR_WIN32)
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#else
|
#else
|
||||||
/**
|
#error "SkCondVar requires pthreads or Windows."
|
||||||
* Warn if the implementation of this class is empty, i.e. thread safety is not working.
|
|
||||||
*/
|
|
||||||
#warning "Thread safety class SkCondVar has no implementation!"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Condition variable for blocking access to shared data from other threads and
|
* Condition variable for blocking access to shared data from other threads and
|
||||||
* controlling which threads are awake.
|
* controlling which threads are awake.
|
||||||
*
|
*
|
||||||
* Currently only supported on platforms with posix threads and Windows Vista and
|
* Currently only supported on platforms with posix threads and Windows Vista and above.
|
||||||
* above.
|
|
||||||
*/
|
*/
|
||||||
class SkCondVar {
|
class SkCondVar {
|
||||||
public:
|
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();
|
||||||
~SkCondVar();
|
~SkCondVar();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user