1/* 2 * Copyright 2013 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8#ifndef SkMutex_win_DEFINED 9#define SkMutex_win_DEFINED 10 11/** Windows CriticalSection based mutex. */ 12 13#ifndef WIN32_LEAN_AND_MEAN 14# define WIN32_LEAN_AND_MEAN 15# define WIN32_IS_MEAN_WAS_LOCALLY_DEFINED 16#endif 17#ifndef NOMINMAX 18# define NOMINMAX 19# define NOMINMAX_WAS_LOCALLY_DEFINED 20#endif 21# 22#include <windows.h> 23# 24#ifdef WIN32_IS_MEAN_WAS_LOCALLY_DEFINED 25# undef WIN32_IS_MEAN_WAS_LOCALLY_DEFINED 26# undef WIN32_LEAN_AND_MEAN 27#endif 28#ifdef NOMINMAX_WAS_LOCALLY_DEFINED 29# undef NOMINMAX_WAS_LOCALLY_DEFINED 30# undef NOMINMAX 31#endif 32 33// On Windows, SkBaseMutex and SkMutex are the same thing, 34// we can't easily get rid of static initializers. However, 35// we preserve the same inheritance pattern as other platforms 36// so that we can forward-declare cleanly. 37struct SkBaseMutex { 38public: 39 SkBaseMutex() { 40 InitializeCriticalSection(&fStorage); 41 SkDEBUGCODE(fOwner = 0;) 42 } 43 44 ~SkBaseMutex() { 45 SkASSERT(0 == fOwner); 46 DeleteCriticalSection(&fStorage); 47 } 48 49 void acquire() { 50 EnterCriticalSection(&fStorage); 51 SkDEBUGCODE(fOwner = GetCurrentThreadId();) 52 } 53 54 void release() { 55 this->assertHeld(); 56 SkDEBUGCODE(fOwner = 0;) 57 LeaveCriticalSection(&fStorage); 58 } 59 60 void assertHeld() { 61 SkASSERT(GetCurrentThreadId() == fOwner); 62 } 63 64protected: 65 CRITICAL_SECTION fStorage; 66 SkDEBUGCODE(DWORD fOwner;) 67 68private: 69 SkBaseMutex(const SkBaseMutex&); 70 SkBaseMutex& operator=(const SkBaseMutex&); 71}; 72 73class SkMutex : public SkBaseMutex { }; 74 75// Windows currently provides no documented means of POD initializing a CRITICAL_SECTION. 76// As a result, it is illegal to SK_DECLARE_STATIC_MUTEX in a function. 77#define SK_DECLARE_STATIC_MUTEX(name) namespace{} static SkBaseMutex name 78 79#endif 80