Add workaround for chaiscript used as static

closes #338
This commit is contained in:
Jason Turner 2017-03-21 11:58:33 -07:00
parent 204faa82c1
commit a281d9571e

View File

@ -75,17 +75,19 @@ namespace chaiscript
~Thread_Storage() ~Thread_Storage()
{ {
t().erase(this); if (!destroyed) {
t().erase(this);
}
} }
inline const T *operator->() const inline const T *operator->() const
{ {
return &(t()[this]); return &(t()[const_cast<Thread_Storage *>(this)]);
} }
inline const T &operator*() const inline const T &operator*() const
{ {
return t()[this]; return t()[const_cast<Thread_Storage *>(this)];
} }
inline T *operator->() inline T *operator->()
@ -98,15 +100,30 @@ namespace chaiscript
return t()[this]; return t()[this];
} }
void *m_key;
private: private:
static std::unordered_map<const void*, T> &t() struct Map_Holder {
std::unordered_map<Thread_Storage<T> *, 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<Thread_Storage<T> *, T> &t()
{ {
thread_local std::unordered_map<const void *, T> my_t; thread_local Map_Holder my_map;
return my_t; return my_map.map;
} }
bool destroyed{false};
}; };
#else // threading disabled #else // threading disabled