diff options
-rw-r--r-- | platform/default/run_loop.cpp | 10 | ||||
-rw-r--r-- | src/mbgl/util/thread.hpp | 4 | ||||
-rw-r--r-- | src/mbgl/util/thread_context.cpp | 85 | ||||
-rw-r--r-- | src/mbgl/util/thread_context.hpp | 65 | ||||
-rw-r--r-- | src/mbgl/util/thread_local.hpp | 59 |
5 files changed, 152 insertions, 71 deletions
diff --git a/platform/default/run_loop.cpp b/platform/default/run_loop.cpp index a0262364ca..845ee1b2ab 100644 --- a/platform/default/run_loop.cpp +++ b/platform/default/run_loop.cpp @@ -1,12 +1,18 @@ #include <mbgl/util/run_loop.hpp> #include <mbgl/util/async_task.hpp> #include <mbgl/util/uv.hpp> +#include <mbgl/util/thread_local.hpp> + +namespace { + +using namespace mbgl::util; +static ThreadLocal<RunLoop>& current = *new ThreadLocal<RunLoop>; + +} namespace mbgl { namespace util { -static uv::tls<RunLoop> current; - RunLoop* RunLoop::Get() { return current.get(); } diff --git a/src/mbgl/util/thread.hpp b/src/mbgl/util/thread.hpp index 7924d3d4cf..e1ea89c392 100644 --- a/src/mbgl/util/thread.hpp +++ b/src/mbgl/util/thread.hpp @@ -112,7 +112,7 @@ Thread<Object>::Thread(const ThreadContext& context, Args&&... args) { template <class Object> template <typename P, std::size_t... I> void Thread<Object>::run(ThreadContext context, P&& params, std::index_sequence<I...>) { - ThreadContext::current.set(&context); + ThreadContext::Set(&context); RunLoop loop_(RunLoop::Type::New); loop = &loop_; @@ -126,7 +126,7 @@ void Thread<Object>::run(ThreadContext context, P&& params, std::index_sequence< loop = nullptr; object = nullptr; - ThreadContext::current.set(nullptr); + ThreadContext::Set(nullptr); joinable.get_future().get(); } diff --git a/src/mbgl/util/thread_context.cpp b/src/mbgl/util/thread_context.cpp index 6742d5e75e..79c75528c5 100644 --- a/src/mbgl/util/thread_context.cpp +++ b/src/mbgl/util/thread_context.cpp @@ -1,30 +1,95 @@ #include <mbgl/util/thread_context.hpp> +#include <mbgl/util/thread_local.hpp> + +#include <cassert> + +namespace { + +using namespace mbgl::util; +static ThreadLocal<ThreadContext>& current = *new ThreadLocal<ThreadContext>; + +} + namespace mbgl { namespace util { +ThreadContext::ThreadContext(const std::string& name_, ThreadType type_, ThreadPriority priority_) + : name(name_), + type(type_), + priority(priority_) { +} + +void ThreadContext::Set(ThreadContext* context) { + current.set(context); +} + +bool ThreadContext::currentlyOn(ThreadType type) { + return current.get()->type == type; +} + +std::string ThreadContext::getName() { + if (current.get() != nullptr) { + return current.get()->name; + } else { + return "Unknown"; + } +} + +ThreadPriority ThreadContext::getPriority() { + if (current.get() != nullptr) { + return current.get()->priority; + } else { + return ThreadPriority::Regular; + } +} + +FileSource* ThreadContext::getFileSource() { + if (current.get() != nullptr) { + return current.get()->fileSource; + } else { + return nullptr; + } +} + +void ThreadContext::setFileSource(FileSource* fileSource) { + if (current.get() != nullptr) { + current.get()->fileSource = fileSource; + } else { + throw new std::runtime_error("Current thread has no current ThreadContext."); + } +} + +GLObjectStore* ThreadContext::getGLObjectStore() { + if (current.get() != nullptr) { + return current.get()->glObjectStore; + } else { + return nullptr; + } +} + +void ThreadContext::setGLObjectStore(GLObjectStore* glObjectStore) { + if (current.get() != nullptr) { + current.get()->glObjectStore = glObjectStore; + } else { + throw new std::runtime_error("Current thread has no current ThreadContext."); + } +} + class MainThreadContextRegistrar { public: MainThreadContextRegistrar() : context("Main", ThreadType::Main, ThreadPriority::Regular) { - ThreadContext::current.set(&context); + ThreadContext::Set(&context); } ~MainThreadContextRegistrar() { - ThreadContext::current.set(nullptr); + ThreadContext::Set(nullptr); } private: ThreadContext context; }; -ThreadContext::ThreadContext(const std::string& name_, ThreadType type_, ThreadPriority priority_) - : name(name_), - type(type_), - priority(priority_) { -} - -uv::tls<ThreadContext> ThreadContext::current; - // Will auto register the main thread context // at startup. Must be instantiated after the // ThreadContext::current object. diff --git a/src/mbgl/util/thread_context.hpp b/src/mbgl/util/thread_context.hpp index 5a91affda8..0c97611ebc 100644 --- a/src/mbgl/util/thread_context.hpp +++ b/src/mbgl/util/thread_context.hpp @@ -1,8 +1,6 @@ #ifndef MBGL_UTIL_THREAD_CONTEXT #define MBGL_UTIL_THREAD_CONTEXT -#include <mbgl/util/uv.hpp> - #include <cstdint> #include <string> #include <thread> @@ -31,70 +29,23 @@ struct ThreadContext { public: ThreadContext(const std::string& name, ThreadType type, ThreadPriority priority); - static bool currentlyOn(ThreadType type) { - return current.get()->type == type; - } - - static std::string getName() { - if (current.get() != nullptr) { - return current.get()->name; - } else { - return "Unknown"; - } - } - - static ThreadPriority getPriority() { - if (current.get() != nullptr) { - return current.get()->priority; - } else { - return ThreadPriority::Regular; - } - } - - static FileSource* getFileSource() { - if (current.get() != nullptr) { - return current.get()->fileSource; - } else { - return nullptr; - } - } + static void Set(ThreadContext* context); - static void setFileSource(FileSource* fileSource) { - if (current.get() != nullptr) { - current.get()->fileSource = fileSource; - } else { - throw new std::runtime_error("Current thread has no current ThreadContext."); - } - } + static bool currentlyOn(ThreadType type); + static std::string getName(); + static ThreadPriority getPriority(); - static GLObjectStore* getGLObjectStore() { - if (current.get() != nullptr) { - return current.get()->glObjectStore; - } else { - return nullptr; - } - } + static FileSource* getFileSource(); + static void setFileSource(FileSource* fileSource); + static GLObjectStore* getGLObjectStore(); + static void setGLObjectStore(GLObjectStore* glObjectStore); - static void setGLObjectStore(GLObjectStore* glObjectStore) { - if (current.get() != nullptr) { - current.get()->glObjectStore = glObjectStore; - } else { - throw new std::runtime_error("Current thread has no current ThreadContext."); - } - } - -private: std::string name; ThreadType type; ThreadPriority priority; FileSource* fileSource = nullptr; GLObjectStore* glObjectStore = nullptr; - - static uv::tls<ThreadContext> current; - - friend class MainThreadContextRegistrar; - template <class Object> friend class Thread; }; } diff --git a/src/mbgl/util/thread_local.hpp b/src/mbgl/util/thread_local.hpp new file mode 100644 index 0000000000..1d580dc238 --- /dev/null +++ b/src/mbgl/util/thread_local.hpp @@ -0,0 +1,59 @@ +#ifndef MBGL_UTIL_THREAD_LOCAL +#define MBGL_UTIL_THREAD_LOCAL + +#include <mbgl/util/noncopyable.hpp> + +#include <stdexcept> + +#include <pthread.h> + +namespace mbgl { +namespace util { + +template <class T> +class ThreadLocal : public noncopyable { +public: + inline ThreadLocal(T* val) { + ThreadLocal(); + set(val); + } + + inline ThreadLocal() { + int ret = pthread_key_create(&key, [](void *ptr) { + delete reinterpret_cast<T *>(ptr); + }); + + if (ret) { + throw new std::runtime_error("Failed to init local storage key."); + } + } + + inline ~ThreadLocal() { + if (pthread_key_delete(key)) { + throw new std::runtime_error("Failed to delete local storage key."); + } + } + + inline T* get() { + T* ret = reinterpret_cast<T*>(pthread_getspecific(key)); + if (!ret) { + return nullptr; + } + + return ret; + } + + inline void set(T* ptr) { + if (pthread_setspecific(key, ptr)) { + throw new std::runtime_error("Failed to set local storage."); + } + } + +private: + pthread_key_t key; +}; + +} +} + +#endif |