1 // Copyright 2015 The Shaderc Authors. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef LIBSHADERC_UTIL_INC_MUTEX_H 16 #define LIBSHADERC_UTIL_INC_MUTEX_H 17 18 // shaderc_util::mutex will be defined and specialized 19 // depending on the platform that is being compiled. 20 // It is more or less conformant to the C++11 specification of std::mutex. 21 // However it does not implement try_lock. 22 23 #ifdef _WIN32 24 // windows.h #defines min and max if we don't define this. 25 // this means things like std::min and std::max break 26 #ifndef NOMINMAX 27 #define NOMINMAX 28 #endif 29 30 #include <windows.h> 31 namespace shaderc_util { 32 33 // As the name suggests, this mutex class is for running on windows. 34 // It conforms to the c++11 mutex implementation, and should be a 35 // drop in replacement. 36 class windows_mutex { 37 public: 38 using native_handle_type = HANDLE; 39 40 windows_mutex() { mutex_ = CreateMutex(nullptr, false, nullptr); } 41 42 ~windows_mutex() { 43 if (mutex_ != INVALID_HANDLE_VALUE) { 44 CloseHandle(mutex_); 45 } 46 } 47 48 windows_mutex(const windows_mutex&) = delete; 49 windows_mutex& operator=(const windows_mutex&) = delete; 50 51 // Locks this mutex, waiting until the mutex is unlocked if it is not already. 52 // It is not valid to lock a mutex that has already been locked. 53 void lock() { WaitForSingleObject(mutex_, INFINITE); } 54 55 // Unlocks this mutex. It is invalid to unlock a mutex that this thread 56 // has not already locked. 57 void unlock() { ReleaseMutex(mutex_); } 58 59 // Returns the native handle for this mutex. In this case a HANDLE object. 60 native_handle_type native_handle() { return mutex_; } 61 62 private: 63 HANDLE mutex_; 64 }; 65 66 using mutex = windows_mutex; 67 } 68 69 #else 70 #include <pthread.h> 71 #include <memory> 72 namespace shaderc_util { 73 74 // As the name suggests, this mutex class is for running with pthreads. 75 // It conforms to the c++11 mutex implementation, and should be a 76 // drop in replacement. 77 class posix_mutex { 78 public: 79 using native_handle_type = pthread_mutex_t*; 80 81 posix_mutex() { pthread_mutex_init(&mutex_, nullptr); } 82 83 ~posix_mutex() { pthread_mutex_destroy(&mutex_); } 84 85 posix_mutex(const posix_mutex&) = delete; 86 posix_mutex& operator=(const posix_mutex&) = delete; 87 88 // Locks this mutex, waiting until the mutex is unlocked if it is not already. 89 // It is not valid to lock a mutex that has already been locked. 90 void lock() { pthread_mutex_lock(&mutex_); } 91 92 // Unlocks this mutex. It is invalid to unlock a mutex that this thread 93 // has not already locked. 94 void unlock() { pthread_mutex_unlock(&mutex_); } 95 96 // Returns the native handle for this mutex. In this case a pthread_mutex_t*. 97 native_handle_type native_handle() { return &mutex_; } 98 99 private: 100 pthread_mutex_t mutex_; 101 }; 102 103 using mutex = posix_mutex; 104 } 105 #endif 106 107 #endif // LIBSHADERC_UTIL_INC_MUTEX_H 108