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.
35class SkMutex {
36public:
37    SkMutex() {
38        InitializeCriticalSection(&fStorage);
39        SkDEBUGCODE(fOwner = 0;)
40    }
41
42    ~SkMutex() {
43        SkASSERT(0 == fOwner);
44        DeleteCriticalSection(&fStorage);
45    }
46
47    void acquire() {
48        EnterCriticalSection(&fStorage);
49        SkDEBUGCODE(fOwner = GetCurrentThreadId();)
50    }
51
52    void release() {
53        this->assertHeld();
54        SkDEBUGCODE(fOwner = 0;)
55        LeaveCriticalSection(&fStorage);
56    }
57
58    void assertHeld() {
59        SkASSERT(GetCurrentThreadId() == fOwner);
60    }
61
62private:
63    SkMutex(const SkMutex&);
64    SkMutex& operator=(const SkMutex&);
65
66    CRITICAL_SECTION fStorage;
67    SkDEBUGCODE(DWORD fOwner;)
68};
69
70typedef SkMutex SkBaseMutex;
71
72// Windows currently provides no documented means of POD initializing a CRITICAL_SECTION.
73#define SK_DECLARE_STATIC_MUTEX(name) static SkBaseMutex name
74#define SK_DECLARE_GLOBAL_MUTEX(name) SkBaseMutex name
75
76#endif
77