Home | History | Annotate | Download | only in sysdeps
      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:
     38     recursive_mutex() {
     39         InitializeCriticalSection(&mutex_);
     40     }
     41 
     42     ~recursive_mutex() {
     43         DeleteCriticalSection(&mutex_);
     44     }
     45 
     46     void lock() {
     47         EnterCriticalSection(&mutex_);
     48     }
     49 
     50     bool try_lock() {
     51         return TryEnterCriticalSection(&mutex_);
     52     }
     53 
     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:
     66     mutex() {
     67     }
     68 
     69     ~mutex() {
     70     }
     71 
     72     void lock() {
     73         mutex_.lock();
     74         if (++lock_count_ != 1) {
     75             fatal("non-recursive mutex locked reentrantly");
     76         }
     77     }
     78 
     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 
     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