#include #include #include #include #include #include #include namespace mbgl { namespace util { template class ThreadLocal::Impl { public: pthread_key_t key; }; template ThreadLocal::ThreadLocal() : impl(std::make_unique()) { int ret = pthread_key_create(&impl->key, [](void *) {}); if (ret) { throw std::runtime_error("Failed to init local storage key."); } } template ThreadLocal::~ThreadLocal() { // ThreadLocal will not take ownership // of the pointer it is managing. The pointer // needs to be explicitly cleared before we // destroy this object. assert(!get()); if (pthread_key_delete(impl->key)) { Log::Error(Event::General, "Failed to delete local storage key."); assert(false); } } template T* ThreadLocal::get() { auto* ret = reinterpret_cast(pthread_getspecific(impl->key)); if (!ret) { return nullptr; } return ret; } template void ThreadLocal::set(T* ptr) { if (pthread_setspecific(impl->key, ptr)) { throw std::runtime_error("Failed to set local storage."); } } template class ThreadLocal; template class ThreadLocal; template class ThreadLocal; // For unit tests } // namespace util } // namespace mbgl