summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThiago Marcos P. Santos <thiago@mapbox.com>2015-11-20 14:30:05 +0200
committerThiago Marcos P. Santos <thiago@mapbox.com>2015-12-01 11:49:02 +0200
commit62990f0a21eab309f03db0d92119a9a299ae475d (patch)
treebf282a7b8728a4eeec6a4d60f62c48e1bccc47be /src
parentc5a437771470382718500ba5cea598ede364b240 (diff)
downloadqtlocation-mapboxgl-62990f0a21eab309f03db0d92119a9a299ae475d.tar.gz
[core] Port uv::tls to pthreads
Diffstat (limited to 'src')
-rw-r--r--src/mbgl/util/thread.hpp4
-rw-r--r--src/mbgl/util/thread_context.cpp85
-rw-r--r--src/mbgl/util/thread_context.hpp65
-rw-r--r--src/mbgl/util/thread_local.hpp59
4 files changed, 144 insertions, 69 deletions
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