/**************************************************************************/1/* mutex.h */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#pragma once3132#include "core/typedefs.h"3334#ifdef MINGW_ENABLED35#define MINGW_STDTHREAD_REDUNDANCY_WARNING36#include "thirdparty/mingw-std-threads/mingw.mutex.h"37#define THREADING_NAMESPACE mingw_stdthread38#else39#include <mutex>40#define THREADING_NAMESPACE std41#endif4243#ifdef THREADS_ENABLED4445template <typename MutexT>46class MutexLock;4748template <typename StdMutexT>49class MutexImpl {50friend class MutexLock<MutexImpl<StdMutexT>>;5152using StdMutexType = StdMutexT;5354mutable StdMutexT mutex;5556public:57_ALWAYS_INLINE_ void lock() const {58mutex.lock();59}6061_ALWAYS_INLINE_ void unlock() const {62mutex.unlock();63}6465_ALWAYS_INLINE_ bool try_lock() const {66return mutex.try_lock();67}68};6970template <typename MutexT>71class MutexLock {72mutable THREADING_NAMESPACE::unique_lock<typename MutexT::StdMutexType> lock;7374public:75explicit MutexLock(const MutexT &p_mutex) :76lock(p_mutex.mutex) {}7778// Clarification: all the funny syntax is needed so this function exists only for binary mutexes.79template <typename T = MutexT>80_ALWAYS_INLINE_ THREADING_NAMESPACE::unique_lock<THREADING_NAMESPACE::mutex> &_get_lock(81typename std::enable_if<std::is_same<T, THREADING_NAMESPACE::mutex>::value> * = nullptr) const {82return lock;83}8485_ALWAYS_INLINE_ void temp_relock() const {86lock.lock();87}8889_ALWAYS_INLINE_ void temp_unlock() const {90lock.unlock();91}9293// TODO: Implement a `try_temp_relock` if needed (will also need a dummy method below).94};9596using Mutex = MutexImpl<THREADING_NAMESPACE::recursive_mutex>; // Recursive, for general use97using BinaryMutex = MutexImpl<THREADING_NAMESPACE::mutex>; // Non-recursive, handle with care9899extern template class MutexImpl<THREADING_NAMESPACE::recursive_mutex>;100extern template class MutexImpl<THREADING_NAMESPACE::mutex>;101extern template class MutexLock<MutexImpl<THREADING_NAMESPACE::recursive_mutex>>;102extern template class MutexLock<MutexImpl<THREADING_NAMESPACE::mutex>>;103104#else // No threads.105106class MutexImpl {107mutable THREADING_NAMESPACE::mutex mutex;108109public:110void lock() const {}111void unlock() const {}112bool try_lock() const { return true; }113};114115template <typename MutexT>116class MutexLock {117public:118MutexLock(const MutexT &p_mutex) {}119120void temp_relock() const {}121void temp_unlock() const {}122};123124using Mutex = MutexImpl;125using BinaryMutex = MutexImpl;126127#endif // THREADS_ENABLED128129130