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