Add assertHeld() to SkMutex.
BUG=skia: R=bungeman@google.com, mtklein@google.com, reed@google.com Author: mtklein@chromium.org Review URL: https://codereview.chromium.org/313823004
This commit is contained in:
parent
919ed4c736
commit
b83f6c3cbd
@ -83,8 +83,9 @@ template <typename T> void sk_release_store(T*, T);
|
||||
|
||||
class SkBaseMutex {
|
||||
public:
|
||||
void acquire();
|
||||
void release();
|
||||
void acquire(); // Block until this thread owns the mutex.
|
||||
void release(); // Assuming this thread owns the mutex, release it.
|
||||
void assertHeld(); // If SK_DEBUG, assert this thread owns the mutex.
|
||||
};
|
||||
|
||||
class SkMutex : SkBaseMutex {
|
||||
@ -128,6 +129,12 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
/** Assert that we're holding the mutex. */
|
||||
void assertHeld() {
|
||||
SkASSERT(fMutex);
|
||||
fMutex->assertHeld();
|
||||
}
|
||||
|
||||
private:
|
||||
SkBaseMutex* fMutex;
|
||||
};
|
||||
|
@ -1737,6 +1737,7 @@ static SkScalar gDeviceGamma = SK_ScalarMin;
|
||||
* the returned SkMaskGamma pointer is refed or forgotten.
|
||||
*/
|
||||
static const SkMaskGamma& cachedMaskGamma(SkScalar contrast, SkScalar paintGamma, SkScalar deviceGamma) {
|
||||
gMaskGammaCacheMutex.assertHeld();
|
||||
if (0 == contrast && SK_Scalar1 == paintGamma && SK_Scalar1 == deviceGamma) {
|
||||
if (NULL == gLinearMaskGamma) {
|
||||
gLinearMaskGamma = SkNEW(SkMaskGamma);
|
||||
|
@ -13,25 +13,25 @@
|
||||
#ifdef SK_USE_POSIX_THREADS
|
||||
|
||||
static SkBaseMutex gPixelRefMutexRing[] = {
|
||||
{ PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER },
|
||||
{ PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER },
|
||||
{ PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER },
|
||||
{ PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER },
|
||||
SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
|
||||
SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
|
||||
SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
|
||||
SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
|
||||
|
||||
{ PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER },
|
||||
{ PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER },
|
||||
{ PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER },
|
||||
{ PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER },
|
||||
SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
|
||||
SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
|
||||
SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
|
||||
SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
|
||||
|
||||
{ PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER },
|
||||
{ PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER },
|
||||
{ PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER },
|
||||
{ PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER },
|
||||
SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
|
||||
SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
|
||||
SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
|
||||
SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
|
||||
|
||||
{ PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER },
|
||||
{ PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER },
|
||||
{ PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER },
|
||||
{ PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_MUTEX_INITIALIZER },
|
||||
SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
|
||||
SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
|
||||
SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
|
||||
SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
|
||||
};
|
||||
|
||||
// must be a power-of-2. undef to just use 1 mutex
|
||||
|
@ -675,6 +675,7 @@ static void cleanup_gScaledImageCache() { SkDELETE(gScaledImageCache); }
|
||||
/** Must hold gMutex when calling. */
|
||||
static SkScaledImageCache* get_cache() {
|
||||
// gMutex is always held when this is called, so we don't need to be fancy in here.
|
||||
gMutex.assertHeld();
|
||||
if (NULL == gScaledImageCache) {
|
||||
#ifdef SK_USE_DISCARDABLE_SCALEDIMAGECACHE
|
||||
gScaledImageCache = SkNEW_ARGS(SkScaledImageCache, (SkDiscardableMemory::Create));
|
||||
|
@ -82,24 +82,20 @@ size_t SkPDFGraphicState::getOutputSize(SkPDFCatalog* catalog, bool indirect) {
|
||||
}
|
||||
|
||||
// static
|
||||
SkTDArray<SkPDFGraphicState::GSCanonicalEntry>&
|
||||
SkPDFGraphicState::CanonicalPaints() {
|
||||
// This initialization is only thread safe with gcc.
|
||||
SkTDArray<SkPDFGraphicState::GSCanonicalEntry>& SkPDFGraphicState::CanonicalPaints() {
|
||||
CanonicalPaintsMutex().assertHeld();
|
||||
static SkTDArray<SkPDFGraphicState::GSCanonicalEntry> gCanonicalPaints;
|
||||
return gCanonicalPaints;
|
||||
}
|
||||
|
||||
// static
|
||||
SkBaseMutex& SkPDFGraphicState::CanonicalPaintsMutex() {
|
||||
// This initialization is only thread safe with gcc or when
|
||||
// POD-style mutex initialization is used.
|
||||
SK_DECLARE_STATIC_MUTEX(gCanonicalPaintsMutex);
|
||||
return gCanonicalPaintsMutex;
|
||||
}
|
||||
|
||||
// static
|
||||
SkPDFGraphicState* SkPDFGraphicState::GetGraphicStateForPaint(
|
||||
const SkPaint& paint) {
|
||||
SkPDFGraphicState* SkPDFGraphicState::GetGraphicStateForPaint(const SkPaint& paint) {
|
||||
SkAutoMutexAcquire lock(CanonicalPaintsMutex());
|
||||
int index = Find(paint);
|
||||
if (index >= 0) {
|
||||
@ -114,6 +110,7 @@ SkPDFGraphicState* SkPDFGraphicState::GetGraphicStateForPaint(
|
||||
// static
|
||||
SkPDFObject* SkPDFGraphicState::GetInvertFunction() {
|
||||
// This assumes that canonicalPaintsMutex is held.
|
||||
CanonicalPaintsMutex().assertHeld();
|
||||
static SkPDFStream* invertFunction = NULL;
|
||||
if (!invertFunction) {
|
||||
// Acrobat crashes if we use a type 0 function, kpdf crashes if we use
|
||||
@ -185,6 +182,7 @@ SkPDFGraphicState* SkPDFGraphicState::GetNoSMaskGraphicState() {
|
||||
|
||||
// static
|
||||
int SkPDFGraphicState::Find(const SkPaint& paint) {
|
||||
CanonicalPaintsMutex().assertHeld();
|
||||
GSCanonicalEntry search(&paint);
|
||||
return CanonicalPaints().find(search);
|
||||
}
|
||||
|
@ -10,16 +10,6 @@
|
||||
|
||||
/** Posix pthread_mutex based mutex. */
|
||||
|
||||
#ifdef SK_DEBUG_PTHREAD_MUTEX
|
||||
#include "SkTypes.h"
|
||||
#define SkDEBUGCODE_PTHREAD_MUTEX(code) code
|
||||
#else
|
||||
#define SkDEBUGCODE_PTHREAD_MUTEX(code)
|
||||
#ifndef SkDebugf
|
||||
void SkDebugf(const char format[], ...);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
|
||||
@ -28,9 +18,21 @@
|
||||
// generation of a static initializer in the final machine code (and
|
||||
// a corresponding static finalizer).
|
||||
struct SkBaseMutex {
|
||||
void acquire() { pthread_mutex_lock(&fMutex); }
|
||||
void release() { pthread_mutex_unlock(&fMutex); }
|
||||
void acquire() {
|
||||
pthread_mutex_lock(&fMutex);
|
||||
SkDEBUGCODE(fOwner = pthread_self();)
|
||||
}
|
||||
void release() {
|
||||
this->assertHeld();
|
||||
SkDEBUGCODE(fOwner = 0;)
|
||||
pthread_mutex_unlock(&fMutex);
|
||||
}
|
||||
void assertHeld() {
|
||||
SkASSERT(pthread_self() == fOwner);
|
||||
}
|
||||
|
||||
pthread_mutex_t fMutex;
|
||||
SkDEBUGCODE(pthread_t fOwner;)
|
||||
};
|
||||
|
||||
// A normal mutex that requires to be initialized through normal C++ construction,
|
||||
@ -38,8 +40,8 @@ struct SkBaseMutex {
|
||||
class SkMutex : public SkBaseMutex {
|
||||
public:
|
||||
SkMutex() {
|
||||
SkDEBUGCODE_PTHREAD_MUTEX(int status = )pthread_mutex_init(&fMutex, NULL);
|
||||
SkDEBUGCODE_PTHREAD_MUTEX(
|
||||
SkDEBUGCODE(int status = )pthread_mutex_init(&fMutex, NULL);
|
||||
SkDEBUGCODE(
|
||||
if (status != 0) {
|
||||
print_pthread_error(status);
|
||||
SkASSERT(0 == status);
|
||||
@ -48,8 +50,8 @@ public:
|
||||
}
|
||||
|
||||
~SkMutex() {
|
||||
SkDEBUGCODE_PTHREAD_MUTEX(int status = )pthread_mutex_destroy(&fMutex);
|
||||
SkDEBUGCODE_PTHREAD_MUTEX(
|
||||
SkDEBUGCODE(int status = )pthread_mutex_destroy(&fMutex);
|
||||
SkDEBUGCODE(
|
||||
if (status != 0) {
|
||||
print_pthread_error(status);
|
||||
SkASSERT(0 == status);
|
||||
@ -78,10 +80,12 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
#define SK_BASE_MUTEX_INIT { PTHREAD_MUTEX_INITIALIZER, SkDEBUGCODE(0) }
|
||||
|
||||
// Using POD-style initialization prevents the generation of a static initializer.
|
||||
#define SK_DECLARE_STATIC_MUTEX(name) static SkBaseMutex name = { PTHREAD_MUTEX_INITIALIZER }
|
||||
#define SK_DECLARE_STATIC_MUTEX(name) static SkBaseMutex name = SK_BASE_MUTEX_INIT
|
||||
|
||||
// Special case used when the static mutex must be available globally.
|
||||
#define SK_DECLARE_GLOBAL_MUTEX(name) SkBaseMutex name = { PTHREAD_MUTEX_INITIALIZER }
|
||||
#define SK_DECLARE_GLOBAL_MUTEX(name) SkBaseMutex name = SK_BASE_MUTEX_INIT
|
||||
|
||||
#endif
|
||||
|
@ -36,25 +36,35 @@ class SkMutex {
|
||||
public:
|
||||
SkMutex() {
|
||||
InitializeCriticalSection(&fStorage);
|
||||
SkDEBUGCODE(fOwner = 0;)
|
||||
}
|
||||
|
||||
~SkMutex() {
|
||||
SkASSERT(0 == fOwner);
|
||||
DeleteCriticalSection(&fStorage);
|
||||
}
|
||||
|
||||
void acquire() {
|
||||
EnterCriticalSection(&fStorage);
|
||||
SkDEBUGCODE(fOwner = GetCurrentThreadId();)
|
||||
}
|
||||
|
||||
void release() {
|
||||
this->assertHeld();
|
||||
SkDEBUGCODE(fOwner = 0;)
|
||||
LeaveCriticalSection(&fStorage);
|
||||
}
|
||||
|
||||
void assertHeld() {
|
||||
SkASSERT(GetCurrentThreadId() == fOwner);
|
||||
}
|
||||
|
||||
private:
|
||||
SkMutex(const SkMutex&);
|
||||
SkMutex& operator=(const SkMutex&);
|
||||
|
||||
CRITICAL_SECTION fStorage;
|
||||
SkDEBUGCODE(DWORD fOwner;)
|
||||
};
|
||||
|
||||
typedef SkMutex SkBaseMutex;
|
||||
|
Loading…
Reference in New Issue
Block a user