diff --git a/src/script/cpp_api/s_base.cpp b/src/script/cpp_api/s_base.cpp index 71369e3d7..679a517ee 100644 --- a/src/script/cpp_api/s_base.cpp +++ b/src/script/cpp_api/s_base.cpp @@ -68,7 +68,7 @@ public: */ 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 d30373ce1..ead385a43 100644 --- a/src/script/cpp_api/s_base.h +++ b/src/script/cpp_api/s_base.h @@ -108,7 +108,7 @@ protected: 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 651fed95f..37473c497 100644 --- a/src/script/cpp_api/s_internal.h +++ b/src/script/cpp_api/s_internal.h @@ -75,7 +75,7 @@ private: #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 dba3ddb4c..43f2b04be 100644 --- a/src/threading/event.h +++ b/src/threading/event.h @@ -29,6 +29,7 @@ DEALINGS IN THE SOFTWARE. #if __cplusplus >= 201103L #include #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 e12b79185..f2b07bec3 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 40b10a2ea..dadbd050c 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 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 @@ private: 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 1c39349e5..25caf7e14 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 - using MutexAutoLock = std::lock_guard; + using MutexAutoLock = std::unique_lock; + using RecursiveMutexAutoLock = std::unique_lock; #else #include "threading/mutex.h" @@ -44,6 +45,15 @@ private: Mutex &mutex; }; +class RecursiveMutexAutoLock +{ +public: + RecursiveMutexAutoLock(RecursiveMutex &m) : mutex(m) { mutex.lock(); } + ~RecursiveMutexAutoLock() { mutex.unlock(); } + +private: + RecursiveMutex &mutex; +}; #endif #endif