From a90a6b2a7ba4648b0e597accbab05763660b7d93 Mon Sep 17 00:00:00 2001 From: Pauli Date: Thu, 5 Jul 2018 21:16:50 +0300 Subject: [PATCH] Make lua data race free Fixes tsan trace report between lua viewscreen and other threads running lua without CoreSuspender lock. But I would assume similar races exists when using lua from console thread, remote thread and vmethods same time. --- depends/lua/CMakeLists.txt | 7 +++++ depends/lualimit.h | 61 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 depends/lualimit.h diff --git a/depends/lua/CMakeLists.txt b/depends/lua/CMakeLists.txt index 7dcae8068..97b62dca6 100644 --- a/depends/lua/CMakeLists.txt +++ b/depends/lua/CMakeLists.txt @@ -95,6 +95,13 @@ LIST(APPEND SRC_LIBLUA ${HDR_LIBLUA}) ADD_LIBRARY ( lua SHARED ${SRC_LIBLUA} ) TARGET_LINK_LIBRARIES ( lua ${LIBS}) +target_include_directories(lua PRIVATE ../) +if (MSVC) + target_compile_options(lua PRIVATE /FI lualimit.h) +else () + target_compile_options(lua PRIVATE -include lualimit.h) +endif () + install(TARGETS lua LIBRARY DESTINATION ${DFHACK_LIBRARY_DESTINATION} RUNTIME DESTINATION ${DFHACK_LIBRARY_DESTINATION}) diff --git a/depends/lualimit.h b/depends/lualimit.h new file mode 100644 index 000000000..009501cce --- /dev/null +++ b/depends/lualimit.h @@ -0,0 +1,61 @@ +/** +Copyright © 2018 Pauli + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must + not claim that you wrote the original software. If you use this + software in a product, an acknowledgment in the product + documentation would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and + must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source + distribution. + */ + +#pragma once + +#ifdef _MSC_VER +#include +#else +#include +#endif + +#include + +/*! \file lualimit.h + * dfhack specific lua porting header that overrides lua defaults for thread + * safety. + */ + +#ifdef _MSC_VER +typedef CRITICAL_SECTION mutex_t; +#else +typedef pthread_mutex_t mutex_t; +#endif + +struct lua_extra_state { + mutex_t* mutex; +}; + +#define luai_mutex(L) ((lua_extra_state*)lua_getextraspace(L))->mutex + +#ifdef _MSC_VER +#define luai_userstateopen(L) luai_mutex(L) = (mutex_t*)malloc(sizeof(mutex_t)); InitializeCriticalSection(luai_mutex(L)) +#define luai_userstateclose(L) lua_unlock(L); DeleteCriticalSection(luai_mutex(L)); free(luai_mutex(L)) +#define lua_lock(L) EnterCriticalSection(luai_mutex(L)) +#define lua_unlock(L) LeaveCriticalSection(luai_mutex(L)) +#else +#define luai_userstateopen(L) luai_mutex(L) = (mutex_t*)malloc(sizeof(mutex_t)); *luai_mutex(L) = PTHREAD_MUTEX_INITIALIZER +#define luai_userstateclose(L) lua_unlock(L); pthread_mutex_destroy(luai_mutex(L)); free(luai_mutex(L)) +#define lua_lock(L) pthread_mutex_lock(luai_mutex(L)) +#define lua_unlock(L) pthread_mutex_unlock(luai_mutex(L)) +#endif