From a281d9571e00788784a10bdae054f92cb3e3fb1a Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Tue, 21 Mar 2017 11:58:33 -0700 Subject: [PATCH] Add workaround for chaiscript used as static closes #338 --- include/chaiscript/chaiscript_threading.hpp | 35 +++++++++++++++------ 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/include/chaiscript/chaiscript_threading.hpp b/include/chaiscript/chaiscript_threading.hpp index 01bda2b..4a25573 100644 --- a/include/chaiscript/chaiscript_threading.hpp +++ b/include/chaiscript/chaiscript_threading.hpp @@ -75,17 +75,19 @@ namespace chaiscript ~Thread_Storage() { - t().erase(this); + if (!destroyed) { + t().erase(this); + } } inline const T *operator->() const { - return &(t()[this]); + return &(t()[const_cast(this)]); } inline const T &operator*() const { - return t()[this]; + return t()[const_cast(this)]; } inline T *operator->() @@ -98,15 +100,30 @@ namespace chaiscript return t()[this]; } - - void *m_key; - private: - static std::unordered_map &t() + struct Map_Holder { + std::unordered_map *, T> map; + + Map_Holder() = default; + Map_Holder(const Map_Holder &) = delete; + Map_Holder(Map_Holder &&) = delete; + Map_Holder& operator=(Map_Holder &&) = delete; + Map_Holder& operator=(const Map_Holder &&) = delete; + ~Map_Holder() { + // here is the theory: + // * If the Map_Holder is destroyed before the Thread_Storage, a flag will get set + // * If destroyed after the Thread_Storage, the * will have been removed from `map` and nothing will happen + for(auto &elem : map) { elem.first->destroyed = true; } + } + }; + + static std::unordered_map *, T> &t() { - thread_local std::unordered_map my_t; - return my_t; + thread_local Map_Holder my_map; + return my_map.map; } + + bool destroyed{false}; }; #else // threading disabled