Refactor thread_id.hpp into cpp and thread_local.hpp
This commit is contained in:
parent
b55483d2d9
commit
13ab8f8111
|
@ -40,6 +40,7 @@ LOCAL_SRC_FILES := \
|
|||
src/object-store/src/impl/android/external_commit_helper.cpp \
|
||||
src/object-store/src/impl/android/weak_realm_notifier.cpp \
|
||||
src/object-store/src/util/format.cpp \
|
||||
src/object-store/src/util/thread_id.cpp \
|
||||
vendor/base64.cpp
|
||||
|
||||
LOCAL_C_INCLUDES := src
|
||||
|
|
|
@ -69,6 +69,8 @@
|
|||
F63FF3261C1642BB00B3B8E0 /* GCDWebServerFileResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = F63FF3181C1642BB00B3B8E0 /* GCDWebServerFileResponse.m */; };
|
||||
F63FF3271C1642BB00B3B8E0 /* GCDWebServerStreamedResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = F63FF31A1C1642BB00B3B8E0 /* GCDWebServerStreamedResponse.m */; };
|
||||
F64A059B1D10D928004ACDBE /* format.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02E008D21D10AB1B00F3AA37 /* format.cpp */; };
|
||||
F64A059D1D13710C004ACDBE /* thread_id.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F64A059C1D13710C004ACDBE /* thread_id.cpp */; };
|
||||
F64A059E1D13710C004ACDBE /* thread_id.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F64A059C1D13710C004ACDBE /* thread_id.cpp */; };
|
||||
F674784A1CC81F1900F9273C /* platform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F67478481CC81F1300F9273C /* platform.cpp */; };
|
||||
F68A278C1BC2722A0063D40A /* RJSModuleLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = F68A278B1BC2722A0063D40A /* RJSModuleLoader.m */; };
|
||||
F6BCCFE21C8380A400FE31AE /* lib in Resources */ = {isa = PBXBuildFile; fileRef = F6BCCFDF1C83809A00FE31AE /* lib */; };
|
||||
|
@ -230,6 +232,8 @@
|
|||
F63FF32C1C16432E00B3B8E0 /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; };
|
||||
F63FF32E1C16433900B3B8E0 /* libxml2.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libxml2.tbd; path = usr/lib/libxml2.tbd; sourceTree = SDKROOT; };
|
||||
F63FF3301C16434400B3B8E0 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; };
|
||||
F64A059C1D13710C004ACDBE /* thread_id.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = thread_id.cpp; sourceTree = "<group>"; };
|
||||
F64A059F1D13716B004ACDBE /* thread_local.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = thread_local.hpp; sourceTree = "<group>"; };
|
||||
F67478481CC81F1300F9273C /* platform.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = platform.cpp; sourceTree = "<group>"; };
|
||||
F6874A351CAC792D00EEEE36 /* node_types.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = node_types.hpp; sourceTree = "<group>"; };
|
||||
F6874A3E1CACA5A900EEEE36 /* js_types.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = js_types.hpp; sourceTree = "<group>"; };
|
||||
|
@ -365,6 +369,8 @@
|
|||
02E008D21D10AB1B00F3AA37 /* format.cpp */,
|
||||
02E008D31D10AB1B00F3AA37 /* format.hpp */,
|
||||
F6242B291D08EE9600BE1E03 /* thread_id.hpp */,
|
||||
F64A059C1D13710C004ACDBE /* thread_id.cpp */,
|
||||
F64A059F1D13716B004ACDBE /* thread_local.hpp */,
|
||||
);
|
||||
name = util;
|
||||
path = src/util;
|
||||
|
@ -790,6 +796,7 @@
|
|||
F6E931BD1CFEAE370016AF14 /* list_notifier.cpp in Sources */,
|
||||
F60102DA1CBB96C300EC01BA /* shared_realm.cpp in Sources */,
|
||||
F60102E01CBB96D900EC01BA /* realm_coordinator.cpp in Sources */,
|
||||
F64A059E1D13710C004ACDBE /* thread_id.cpp in Sources */,
|
||||
F60102EA1CBCAFC300EC01BA /* node_dummy.cpp in Sources */,
|
||||
F60102D81CBB96BD00EC01BA /* results.cpp in Sources */,
|
||||
F674784A1CC81F1900F9273C /* platform.cpp in Sources */,
|
||||
|
@ -805,6 +812,7 @@
|
|||
02E008D51D10ABB600F3AA37 /* format.cpp in Sources */,
|
||||
02414BA51CE6ABCF00A8669F /* collection_change_builder.cpp in Sources */,
|
||||
02414BA61CE6ABCF00A8669F /* collection_notifier.cpp in Sources */,
|
||||
F64A059D1D13710C004ACDBE /* thread_id.cpp in Sources */,
|
||||
02414BA71CE6ABCF00A8669F /* list_notifier.cpp in Sources */,
|
||||
02414BA81CE6ABCF00A8669F /* results_notifier.cpp in Sources */,
|
||||
02414BA91CE6ABCF00A8669F /* collection_notifications.cpp in Sources */,
|
||||
|
|
|
@ -24,7 +24,8 @@
|
|||
"../object-store/src/impl/node/weak_realm_notifier.cpp",
|
||||
"../object-store/src/parser/parser.cpp",
|
||||
"../object-store/src/parser/query_builder.cpp",
|
||||
"../object-store/src/util/format.cpp"
|
||||
"../object-store/src/util/format.cpp",
|
||||
"../object-store/src/util/thread_id.cpp"
|
||||
],
|
||||
"include_dirs": [
|
||||
"..",
|
||||
|
|
|
@ -15,7 +15,8 @@ set(SOURCES
|
|||
impl/transact_log_handler.cpp
|
||||
parser/parser.cpp
|
||||
parser/query_builder.cpp
|
||||
util/format.cpp)
|
||||
util/format.cpp
|
||||
util/thread_id.cpp)
|
||||
|
||||
set(HEADERS
|
||||
collection_notifications.hpp
|
||||
|
@ -39,7 +40,9 @@ set(HEADERS
|
|||
parser/parser.hpp
|
||||
parser/query_builder.hpp
|
||||
util/atomic_shared_ptr.hpp
|
||||
util/format.hpp)
|
||||
util/format.hpp
|
||||
util/thread_id.hpp
|
||||
util/thread_local.hpp)
|
||||
|
||||
if(APPLE)
|
||||
list(APPEND SOURCES
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright 2016 Realm Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "thread_id.hpp"
|
||||
#include "thread_local.hpp"
|
||||
|
||||
#include <atomic>
|
||||
|
||||
using namespace realm;
|
||||
|
||||
// Since std::thread::id may be reused after a thread is destroyed, we use
|
||||
// an atomically incremented, thread-local identifier instead.
|
||||
thread_id_t realm::util::get_thread_id() {
|
||||
static std::atomic<thread_id_t> id_counter;
|
||||
static REALM_THREAD_LOCAL_TYPE(thread_id_t) thread_id = 0;
|
||||
|
||||
if (REALM_UNLIKELY(!thread_id)) {
|
||||
thread_id = ++id_counter;
|
||||
}
|
||||
|
||||
return thread_id;
|
||||
}
|
|
@ -19,84 +19,17 @@
|
|||
#ifndef REALM_THREAD_ID_HPP
|
||||
#define REALM_THREAD_ID_HPP
|
||||
|
||||
#include <realm/util/features.h>
|
||||
|
||||
#include <atomic>
|
||||
|
||||
#if __has_feature(tls) || __has_feature(cxx_thread_local)
|
||||
#define REALM_HAS_THREAD_LOCAL 1
|
||||
#else
|
||||
#define REALM_HAS_THREAD_LOCAL 0
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
#include <cstddef>
|
||||
|
||||
namespace realm {
|
||||
|
||||
using thread_id_t = std::size_t;
|
||||
|
||||
namespace _impl {
|
||||
|
||||
#if !REALM_HAS_THREAD_LOCAL
|
||||
template<typename T>
|
||||
class ThreadLocal {
|
||||
public:
|
||||
ThreadLocal() : m_initial_value() {
|
||||
init_key();
|
||||
}
|
||||
ThreadLocal(const T &value) : m_initial_value(value) {
|
||||
init_key();
|
||||
}
|
||||
~ThreadLocal() {
|
||||
pthread_key_delete(m_key);
|
||||
}
|
||||
|
||||
operator T&() {
|
||||
void* ptr = pthread_getspecific(m_key);
|
||||
if (!ptr) {
|
||||
ptr = new T(m_initial_value);
|
||||
pthread_setspecific(m_key, ptr);
|
||||
}
|
||||
return *static_cast<T*>(ptr);
|
||||
}
|
||||
T& operator=(const T &value) {
|
||||
T& value_ref = operator T&();
|
||||
value_ref = value;
|
||||
return value_ref;
|
||||
}
|
||||
|
||||
private:
|
||||
T m_initial_value;
|
||||
pthread_key_t m_key;
|
||||
|
||||
void init_key() {
|
||||
pthread_key_create(&m_key, [](void* ptr) {
|
||||
delete static_cast<T*>(ptr);
|
||||
});
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
} // namespace _impl
|
||||
|
||||
namespace util {
|
||||
|
||||
// Since std::thread::id may be reused after a thread is destroyed, we use
|
||||
// an atomically incremented, thread-local identifier instead.
|
||||
inline thread_id_t get_thread_id() {
|
||||
static std::atomic<thread_id_t> id_counter;
|
||||
|
||||
#if REALM_HAS_THREAD_LOCAL
|
||||
static REALM_THREAD_LOCAL thread_id_t thread_id = 0;
|
||||
#else
|
||||
static _impl::ThreadLocal<thread_id_t> thread_id = 0;
|
||||
#endif
|
||||
|
||||
if (REALM_UNLIKELY(!thread_id)) {
|
||||
thread_id = ++id_counter;
|
||||
}
|
||||
|
||||
return thread_id;
|
||||
}
|
||||
thread_id_t get_thread_id();
|
||||
|
||||
} // namespace util
|
||||
} // namespace realm
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright 2016 Realm Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef REALM_THREAD_LOCAL_HPP
|
||||
#define REALM_THREAD_LOCAL_HPP
|
||||
|
||||
#include <realm/util/features.h>
|
||||
|
||||
#if __has_feature(tls) || __has_feature(cxx_thread_local)
|
||||
|
||||
#define REALM_THREAD_LOCAL_TYPE(type) REALM_THREAD_LOCAL type
|
||||
|
||||
#else
|
||||
|
||||
#define REALM_THREAD_LOCAL_TYPE(type) realm::_impl::ThreadLocal<type>
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
namespace realm {
|
||||
namespace _impl {
|
||||
|
||||
template<typename T>
|
||||
class ThreadLocal {
|
||||
public:
|
||||
ThreadLocal() : m_initial_value() {
|
||||
init_key();
|
||||
}
|
||||
ThreadLocal(const T &value) : m_initial_value(value) {
|
||||
init_key();
|
||||
}
|
||||
~ThreadLocal() {
|
||||
pthread_key_delete(m_key);
|
||||
}
|
||||
|
||||
operator T&() {
|
||||
void* ptr = pthread_getspecific(m_key);
|
||||
if (!ptr) {
|
||||
ptr = new T(m_initial_value);
|
||||
pthread_setspecific(m_key, ptr);
|
||||
}
|
||||
return *static_cast<T*>(ptr);
|
||||
}
|
||||
T& operator=(const T &value) {
|
||||
T& value_ref = operator T&();
|
||||
value_ref = value;
|
||||
return value_ref;
|
||||
}
|
||||
|
||||
private:
|
||||
T m_initial_value;
|
||||
pthread_key_t m_key;
|
||||
|
||||
void init_key() {
|
||||
pthread_key_create(&m_key, [](void* ptr) {
|
||||
delete static_cast<T*>(ptr);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace _impl
|
||||
} // namespace realm
|
||||
|
||||
#endif
|
||||
#endif // REALM_THREAD_LOCAL_HPP
|
Loading…
Reference in New Issue