1 #pragma once
2 
3 /*
4  * Copyright (C) 2016 The Android Open Source Project
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 #if defined(_WIN32)
20 
21 #include <windows.h>
22 
23 #include <android-base/macros.h>
24 
25 #include "adb.h"
26 
27 // The prebuilt version of mingw we use doesn't support mutex or recursive_mutex.
28 // Therefore, implement our own using the Windows primitives.
29 // Put them directly into the std namespace, so that when they're actually available, the build
30 // breaks until they're removed.
31 
32 #include <mutex>
33 namespace std {
34 
35 // CRITICAL_SECTION is recursive, so just wrap it in a Mutex-compatible class.
36 class recursive_mutex {
37   public:
recursive_mutex()38     recursive_mutex() {
39         InitializeCriticalSection(&mutex_);
40     }
41 
~recursive_mutex()42     ~recursive_mutex() {
43         DeleteCriticalSection(&mutex_);
44     }
45 
lock()46     void lock() {
47         EnterCriticalSection(&mutex_);
48     }
49 
try_lock()50     bool try_lock() {
51         return TryEnterCriticalSection(&mutex_);
52     }
53 
unlock()54     void unlock() {
55         LeaveCriticalSection(&mutex_);
56     }
57 
58   private:
59     CRITICAL_SECTION mutex_;
60 
61     DISALLOW_COPY_AND_ASSIGN(recursive_mutex);
62 };
63 
64 class mutex {
65   public:
mutex()66     mutex() {
67     }
68 
~mutex()69     ~mutex() {
70     }
71 
lock()72     void lock() {
73         mutex_.lock();
74         if (++lock_count_ != 1) {
75             fatal("non-recursive mutex locked reentrantly");
76         }
77     }
78 
unlock()79     void unlock() {
80         if (--lock_count_ != 0) {
81             fatal("non-recursive mutex unlock resulted in unexpected lock count: %d", lock_count_);
82         }
83         mutex_.unlock();
84     }
85 
try_lock()86     bool try_lock() {
87         if (!mutex_.try_lock()) {
88             return false;
89         }
90 
91         if (lock_count_ != 0) {
92             mutex_.unlock();
93             return false;
94         }
95 
96         ++lock_count_;
97         return true;
98     }
99 
100   private:
101     recursive_mutex mutex_;
102     size_t lock_count_ = 0;
103 };
104 
105 }
106 
107 #endif
108