From 4d3c28158a65f9eac6b472dff29caa77b44f8134 Mon Sep 17 00:00:00 2001 From: "scroggo@google.com" Date: Wed, 31 Oct 2012 19:29:13 +0000 Subject: Implement SkCondVar for windows. Only works on Vista or later, since it uses condition variables. Review URL: https://codereview.appspot.com/6812062 git-svn-id: http://skia.googlecode.com/svn/trunk@6225 2bbb7eff-a529-9590-31e7-b0007b416f81 --- gyp/utils.gyp | 9 --------- include/utils/SkCondVar.h | 29 ++++++++++++++++++++++++++--- src/utils/SkCondVar.cpp | 30 ++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 12 deletions(-) diff --git a/gyp/utils.gyp b/gyp/utils.gyp index 61cfd127b7..97f25b158d 100644 --- a/gyp/utils.gyp +++ b/gyp/utils.gyp @@ -156,15 +156,6 @@ '../src/utils/SkThreadUtils_pthread.cpp', '../src/utils/SkThreadUtils_pthread.h', '../src/utils/SkThreadUtils_pthread_other.cpp', - - # SkThreadPool and related currently depend on pthread. - '../include/utils/SkCondVar.h', - '../include/utils/SkCountdown.h', - '../include/utils/SkRunnable.h', - '../include/utils/SkThreadPool.h', - '../src/utils/SkCondVar.cpp', - '../src/utils/SkCountdown.cpp', - '../src/utils/SkThreadPool.cpp', ], },{ #else if 'skia_os != "win"' 'include_dirs!': [ diff --git a/include/utils/SkCondVar.h b/include/utils/SkCondVar.h index d2539e4b9e..15f16e662f 100644 --- a/include/utils/SkCondVar.h +++ b/include/utils/SkCondVar.h @@ -8,19 +8,38 @@ #ifndef SkCondVar_DEFINED #define SkCondVar_DEFINED +#ifdef SK_USE_POSIX_THREADS #include +#elif defined(SK_BUILD_FOR_WIN32) +#include +#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. + */ class SkCondVar { public: SkCondVar(); ~SkCondVar(); + /** + * Lock a mutex. Must be done before calling the other functions on this object. + */ void lock(); + + /** + * Unlock the mutex. + */ void unlock(); /** - * Pause the calling thread. Will be awoken when signal() is called. - * Must be called while lock() is held (but gives it up while waiting). + * Pause the calling thread. Will be awoken when signal() or broadcast() is called. + * Must be called while lock() is held (but gives it up while waiting). Once awoken, + * the calling thread will hold the lock once again. */ void wait(); @@ -37,9 +56,13 @@ public: void broadcast(); private: - // FIXME: Make this independent of pthreads. +#ifdef SK_USE_POSIX_THREADS pthread_mutex_t fMutex; pthread_cond_t fCond; +#elif defined(SK_BUILD_FOR_WIN32) + CRITICAL_SECTION fCriticalSection; + CONDITION_VARIABLE fCondition; +#endif }; #endif diff --git a/src/utils/SkCondVar.cpp b/src/utils/SkCondVar.cpp index 8cbab58de2..5d001c0edd 100644 --- a/src/utils/SkCondVar.cpp +++ b/src/utils/SkCondVar.cpp @@ -8,31 +8,61 @@ #include "SkCondVar.h" 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); +#endif } SkCondVar::~SkCondVar() { +#ifdef SK_USE_POSIX_THREADS pthread_mutex_destroy(&fMutex); pthread_cond_destroy(&fCond); +#elif defined(SK_BUILD_FOR_WIN32) + DeleteCriticalSection(&fCriticalSection); + // No need to clean up fCondition. +#endif } void SkCondVar::lock() { +#ifdef SK_USE_POSIX_THREADS pthread_mutex_lock(&fMutex); +#elif defined(SK_BUILD_FOR_WIN32) + EnterCriticalSection(&fCriticalSection); +#endif } void SkCondVar::unlock() { +#ifdef SK_USE_POSIX_THREADS pthread_mutex_unlock(&fMutex); +#elif defined(SK_BUILD_FOR_WIN32) + LeaveCriticalSection(&fCriticalSection); +#endif } void SkCondVar::wait() { +#ifdef SK_USE_POSIX_THREADS pthread_cond_wait(&fCond, &fMutex); +#elif defined(SK_BUILD_FOR_WIN32) + SleepConditionVariableCS(&fCondition, &fCriticalSection, INFINITE); +#endif } void SkCondVar::signal() { +#ifdef SK_USE_POSIX_THREADS pthread_cond_signal(&fCond); +#elif defined(SK_BUILD_FOR_WIN32) + WakeConditionVariable(&fCondition); +#endif } void SkCondVar::broadcast() { +#ifdef SK_USE_POSIX_THREADS pthread_cond_broadcast(&fCond); +#elif defined(SK_BUILD_FOR_WIN32) + WakeAllConditionVariable(&fCondition); +#endif } -- cgit v1.2.3