diff --git a/src/script/cpp_api/s_base.cpp b/src/script/cpp_api/s_base.cpp index 71369e3d75ce0924297f02e5fefbfc548e88d2d4..679a517ee0b84c9c4685b9abf69126560ceb05ab 100644 --- a/src/script/cpp_api/s_base.cpp +++ b/src/script/cpp_api/s_base.cpp @@ -68,7 +68,7 @@ class ModNameStorer */ ScriptApiBase::ScriptApiBase() : - m_luastackmutex(true) + m_luastackmutex() { #ifdef SCRIPTAPI_LOCK_DEBUG m_lock_recursion_count = 0; diff --git a/src/script/cpp_api/s_base.h b/src/script/cpp_api/s_base.h index d30373ce1520a25a20cb7abc16b4b1ec4ff7f64d..ead385a439f3f60d2854494d6ced8959a76778f8 100644 --- a/src/script/cpp_api/s_base.h +++ b/src/script/cpp_api/s_base.h @@ -108,7 +108,7 @@ class ScriptApiBase { void objectrefGetOrCreate(lua_State *L, ServerActiveObject *cobj); void objectrefGet(lua_State *L, u16 id); - Mutex m_luastackmutex; + RecursiveMutex m_luastackmutex; std::string m_last_run_mod; bool m_secure; #ifdef SCRIPTAPI_LOCK_DEBUG diff --git a/src/script/cpp_api/s_internal.h b/src/script/cpp_api/s_internal.h index 651fed95f4c609de503dcc68e34f2855836b6dee..37473c497e776def17d6842df046e56a74b5b99b 100644 --- a/src/script/cpp_api/s_internal.h +++ b/src/script/cpp_api/s_internal.h @@ -75,7 +75,7 @@ class LockChecker { #endif #define SCRIPTAPI_PRECHECKHEADER \ - MutexAutoLock scriptlock(this->m_luastackmutex); \ + RecursiveMutexAutoLock scriptlock(this->m_luastackmutex); \ SCRIPTAPI_LOCK_CHECK; \ realityCheck(); \ lua_State *L = getStack(); \ diff --git a/src/threading/event.h b/src/threading/event.h index dba3ddb4c28576c77d7f1c4613d34b7178470974..43f2b04bed793c8db44b35e2fcbe29c694a7a0fd 100644 --- a/src/threading/event.h +++ b/src/threading/event.h @@ -29,6 +29,7 @@ DEALINGS IN THE SOFTWARE. #if __cplusplus >= 201103L #include <condition_variable> #include "threading/mutex.h" + #include "threading/mutex_auto_lock.h" #elif defined(_WIN32) #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN diff --git a/src/threading/mutex.cpp b/src/threading/mutex.cpp index e12b791851bf289aa1f109cab25baa645f2e54b0..f2b07bec374b354420e8c3691a83e489b46e587d 100644 --- a/src/threading/mutex.cpp +++ b/src/threading/mutex.cpp @@ -34,7 +34,18 @@ DEALINGS IN THE SOFTWARE. #define UNUSED(expr) do { (void)(expr); } while (0) +Mutex::Mutex() +{ + init_mutex(false); +} + + Mutex::Mutex(bool recursive) +{ + init_mutex(recursive); +} + +void Mutex::init_mutex(bool recursive) { #ifdef _WIN32 // Windows critical sections are recursive by default @@ -89,5 +100,9 @@ void Mutex::unlock() #endif } +RecursiveMutex::RecursiveMutex() + : Mutex(true) +{} + #endif diff --git a/src/threading/mutex.h b/src/threading/mutex.h index 40b10a2ea05995b1060901b44cd5ecd8f15c2285..dadbd050c051d8fc6bd20236d40672242ae56f04 100644 --- a/src/threading/mutex.h +++ b/src/threading/mutex.h @@ -30,6 +30,7 @@ DEALINGS IN THE SOFTWARE. #if __cplusplus >= 201103L && !defined(_WIN32) #include <mutex> using Mutex = std::mutex; + using RecursiveMutex = std::recursive_mutex; #else #ifdef _WIN32 @@ -49,11 +50,14 @@ DEALINGS IN THE SOFTWARE. class Mutex { public: - Mutex(bool recursive=false); + Mutex(); ~Mutex(); void lock(); void unlock(); +protected: + Mutex(bool recursive); + void init_mutex(bool recursive); private: #ifdef _WIN32 CRITICAL_SECTION mutex; @@ -64,6 +68,14 @@ class Mutex DISABLE_CLASS_COPY(Mutex); }; +class RecursiveMutex : public Mutex +{ +public: + RecursiveMutex(); + + DISABLE_CLASS_COPY(RecursiveMutex); +}; + #endif // C++11 #endif diff --git a/src/threading/mutex_auto_lock.h b/src/threading/mutex_auto_lock.h index 1c39349e50bd22fa4a4cf4ca37d3d716c4c922ce..25caf7e140d9d7bfbbd89036c46cd0275d473678 100644 --- a/src/threading/mutex_auto_lock.h +++ b/src/threading/mutex_auto_lock.h @@ -28,7 +28,8 @@ DEALINGS IN THE SOFTWARE. #if __cplusplus >= 201103L #include <mutex> - using MutexAutoLock = std::lock_guard<std::mutex>; + using MutexAutoLock = std::unique_lock<std::mutex>; + using RecursiveMutexAutoLock = std::unique_lock<std::recursive_mutex>; #else #include "threading/mutex.h" @@ -44,6 +45,15 @@ class MutexAutoLock Mutex &mutex; }; +class RecursiveMutexAutoLock +{ +public: + RecursiveMutexAutoLock(RecursiveMutex &m) : mutex(m) { mutex.lock(); } + ~RecursiveMutexAutoLock() { mutex.unlock(); } + +private: + RecursiveMutex &mutex; +}; #endif #endif