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> 31namespace 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. 36class 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 66using mutex = windows_mutex; 67} 68 69#else 70#include <pthread.h> 71#include <memory> 72namespace 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. 77class 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 103using mutex = posix_mutex; 104} 105#endif 106 107#endif // LIBSHADERC_UTIL_INC_MUTEX_H 108