mirror of
https://github.com/status-im/realm-js.git
synced 2025-01-11 23:04:29 +00:00
Merge pull request #480 from realm/sk-thread-id-fix
Fix bug due to std:🧵:id being reused
This commit is contained in:
commit
7931f1d483
@ -40,6 +40,7 @@ LOCAL_SRC_FILES := \
|
|||||||
src/object-store/src/impl/android/external_commit_helper.cpp \
|
src/object-store/src/impl/android/external_commit_helper.cpp \
|
||||||
src/object-store/src/impl/android/weak_realm_notifier.cpp \
|
src/object-store/src/impl/android/weak_realm_notifier.cpp \
|
||||||
src/object-store/src/util/format.cpp \
|
src/object-store/src/util/format.cpp \
|
||||||
|
src/object-store/src/util/thread_id.cpp \
|
||||||
vendor/base64.cpp
|
vendor/base64.cpp
|
||||||
|
|
||||||
LOCAL_C_INCLUDES := src
|
LOCAL_C_INCLUDES := src
|
||||||
|
@ -69,6 +69,8 @@
|
|||||||
F63FF3261C1642BB00B3B8E0 /* GCDWebServerFileResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = F63FF3181C1642BB00B3B8E0 /* GCDWebServerFileResponse.m */; };
|
F63FF3261C1642BB00B3B8E0 /* GCDWebServerFileResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = F63FF3181C1642BB00B3B8E0 /* GCDWebServerFileResponse.m */; };
|
||||||
F63FF3271C1642BB00B3B8E0 /* GCDWebServerStreamedResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = F63FF31A1C1642BB00B3B8E0 /* GCDWebServerStreamedResponse.m */; };
|
F63FF3271C1642BB00B3B8E0 /* GCDWebServerStreamedResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = F63FF31A1C1642BB00B3B8E0 /* GCDWebServerStreamedResponse.m */; };
|
||||||
F64A059B1D10D928004ACDBE /* format.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02E008D21D10AB1B00F3AA37 /* format.cpp */; };
|
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 */; };
|
F674784A1CC81F1900F9273C /* platform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F67478481CC81F1300F9273C /* platform.cpp */; };
|
||||||
F68A278C1BC2722A0063D40A /* RJSModuleLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = F68A278B1BC2722A0063D40A /* RJSModuleLoader.m */; };
|
F68A278C1BC2722A0063D40A /* RJSModuleLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = F68A278B1BC2722A0063D40A /* RJSModuleLoader.m */; };
|
||||||
F6BCCFE21C8380A400FE31AE /* lib in Resources */ = {isa = PBXBuildFile; fileRef = F6BCCFDF1C83809A00FE31AE /* lib */; };
|
F6BCCFE21C8380A400FE31AE /* lib in Resources */ = {isa = PBXBuildFile; fileRef = F6BCCFDF1C83809A00FE31AE /* lib */; };
|
||||||
@ -189,6 +191,7 @@
|
|||||||
F620F0571CB766DA0082977B /* node_init.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = node_init.cpp; sourceTree = "<group>"; };
|
F620F0571CB766DA0082977B /* node_init.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = node_init.cpp; sourceTree = "<group>"; };
|
||||||
F620F0591CB7B4C80082977B /* js_object_accessor.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = js_object_accessor.hpp; sourceTree = "<group>"; };
|
F620F0591CB7B4C80082977B /* js_object_accessor.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = js_object_accessor.hpp; sourceTree = "<group>"; };
|
||||||
F620F0741CB9F60C0082977B /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/System/Library/Frameworks/CoreFoundation.framework; sourceTree = DEVELOPER_DIR; };
|
F620F0741CB9F60C0082977B /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/System/Library/Frameworks/CoreFoundation.framework; sourceTree = DEVELOPER_DIR; };
|
||||||
|
F6242B291D08EE9600BE1E03 /* thread_id.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = thread_id.hpp; sourceTree = "<group>"; };
|
||||||
F6267BC91CADC30000AC36B1 /* js_util.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = js_util.hpp; sourceTree = "<group>"; };
|
F6267BC91CADC30000AC36B1 /* js_util.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = js_util.hpp; sourceTree = "<group>"; };
|
||||||
F6267BCA1CADC49200AC36B1 /* node_dummy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = node_dummy.cpp; sourceTree = "<group>"; };
|
F6267BCA1CADC49200AC36B1 /* node_dummy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = node_dummy.cpp; sourceTree = "<group>"; };
|
||||||
F62BF8FB1CAC71780022BCDC /* libRealmNode.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libRealmNode.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
|
F62BF8FB1CAC71780022BCDC /* libRealmNode.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libRealmNode.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
@ -229,6 +232,8 @@
|
|||||||
F63FF32C1C16432E00B3B8E0 /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; };
|
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; };
|
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; };
|
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>"; };
|
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>"; };
|
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>"; };
|
F6874A3E1CACA5A900EEEE36 /* js_types.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = js_types.hpp; sourceTree = "<group>"; };
|
||||||
@ -363,6 +368,9 @@
|
|||||||
02E008D11D10AB1B00F3AA37 /* atomic_shared_ptr.hpp */,
|
02E008D11D10AB1B00F3AA37 /* atomic_shared_ptr.hpp */,
|
||||||
02E008D21D10AB1B00F3AA37 /* format.cpp */,
|
02E008D21D10AB1B00F3AA37 /* format.cpp */,
|
||||||
02E008D31D10AB1B00F3AA37 /* format.hpp */,
|
02E008D31D10AB1B00F3AA37 /* format.hpp */,
|
||||||
|
F6242B291D08EE9600BE1E03 /* thread_id.hpp */,
|
||||||
|
F64A059C1D13710C004ACDBE /* thread_id.cpp */,
|
||||||
|
F64A059F1D13716B004ACDBE /* thread_local.hpp */,
|
||||||
);
|
);
|
||||||
name = util;
|
name = util;
|
||||||
path = src/util;
|
path = src/util;
|
||||||
@ -788,6 +796,7 @@
|
|||||||
F6E931BD1CFEAE370016AF14 /* list_notifier.cpp in Sources */,
|
F6E931BD1CFEAE370016AF14 /* list_notifier.cpp in Sources */,
|
||||||
F60102DA1CBB96C300EC01BA /* shared_realm.cpp in Sources */,
|
F60102DA1CBB96C300EC01BA /* shared_realm.cpp in Sources */,
|
||||||
F60102E01CBB96D900EC01BA /* realm_coordinator.cpp in Sources */,
|
F60102E01CBB96D900EC01BA /* realm_coordinator.cpp in Sources */,
|
||||||
|
F64A059E1D13710C004ACDBE /* thread_id.cpp in Sources */,
|
||||||
F60102EA1CBCAFC300EC01BA /* node_dummy.cpp in Sources */,
|
F60102EA1CBCAFC300EC01BA /* node_dummy.cpp in Sources */,
|
||||||
F60102D81CBB96BD00EC01BA /* results.cpp in Sources */,
|
F60102D81CBB96BD00EC01BA /* results.cpp in Sources */,
|
||||||
F674784A1CC81F1900F9273C /* platform.cpp in Sources */,
|
F674784A1CC81F1900F9273C /* platform.cpp in Sources */,
|
||||||
@ -803,6 +812,7 @@
|
|||||||
02E008D51D10ABB600F3AA37 /* format.cpp in Sources */,
|
02E008D51D10ABB600F3AA37 /* format.cpp in Sources */,
|
||||||
02414BA51CE6ABCF00A8669F /* collection_change_builder.cpp in Sources */,
|
02414BA51CE6ABCF00A8669F /* collection_change_builder.cpp in Sources */,
|
||||||
02414BA61CE6ABCF00A8669F /* collection_notifier.cpp in Sources */,
|
02414BA61CE6ABCF00A8669F /* collection_notifier.cpp in Sources */,
|
||||||
|
F64A059D1D13710C004ACDBE /* thread_id.cpp in Sources */,
|
||||||
02414BA71CE6ABCF00A8669F /* list_notifier.cpp in Sources */,
|
02414BA71CE6ABCF00A8669F /* list_notifier.cpp in Sources */,
|
||||||
02414BA81CE6ABCF00A8669F /* results_notifier.cpp in Sources */,
|
02414BA81CE6ABCF00A8669F /* results_notifier.cpp in Sources */,
|
||||||
02414BA91CE6ABCF00A8669F /* collection_notifications.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/impl/node/weak_realm_notifier.cpp",
|
||||||
"../object-store/src/parser/parser.cpp",
|
"../object-store/src/parser/parser.cpp",
|
||||||
"../object-store/src/parser/query_builder.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": [
|
"include_dirs": [
|
||||||
"..",
|
"..",
|
||||||
|
@ -15,7 +15,8 @@ set(SOURCES
|
|||||||
impl/transact_log_handler.cpp
|
impl/transact_log_handler.cpp
|
||||||
parser/parser.cpp
|
parser/parser.cpp
|
||||||
parser/query_builder.cpp
|
parser/query_builder.cpp
|
||||||
util/format.cpp)
|
util/format.cpp
|
||||||
|
util/thread_id.cpp)
|
||||||
|
|
||||||
set(HEADERS
|
set(HEADERS
|
||||||
collection_notifications.hpp
|
collection_notifications.hpp
|
||||||
@ -39,7 +40,9 @@ set(HEADERS
|
|||||||
parser/parser.hpp
|
parser/parser.hpp
|
||||||
parser/query_builder.hpp
|
parser/query_builder.hpp
|
||||||
util/atomic_shared_ptr.hpp
|
util/atomic_shared_ptr.hpp
|
||||||
util/format.hpp)
|
util/format.hpp
|
||||||
|
util/thread_id.hpp
|
||||||
|
util/thread_local.hpp)
|
||||||
|
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
list(APPEND SOURCES
|
list(APPEND SOURCES
|
||||||
|
@ -19,8 +19,9 @@
|
|||||||
#ifndef REALM_WEAK_REALM_NOTIFIER_BASE_HPP
|
#ifndef REALM_WEAK_REALM_NOTIFIER_BASE_HPP
|
||||||
#define REALM_WEAK_REALM_NOTIFIER_BASE_HPP
|
#define REALM_WEAK_REALM_NOTIFIER_BASE_HPP
|
||||||
|
|
||||||
|
#include "util/thread_id.hpp"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <thread>
|
|
||||||
|
|
||||||
namespace realm {
|
namespace realm {
|
||||||
class Realm;
|
class Realm;
|
||||||
@ -48,11 +49,11 @@ public:
|
|||||||
// Is this a WeakRealmNotifierBase for the given Realm instance?
|
// Is this a WeakRealmNotifierBase for the given Realm instance?
|
||||||
bool is_for_realm(Realm* realm) const { return realm == m_realm_key; }
|
bool is_for_realm(Realm* realm) const { return realm == m_realm_key; }
|
||||||
|
|
||||||
bool is_for_current_thread() const { return m_thread_id == std::this_thread::get_id(); }
|
bool is_for_current_thread() const { return m_thread_id == util::get_thread_id(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::weak_ptr<Realm> m_realm;
|
std::weak_ptr<Realm> m_realm;
|
||||||
std::thread::id m_thread_id = std::this_thread::get_id();
|
thread_id_t m_thread_id = util::get_thread_id();
|
||||||
void* m_realm_key;
|
void* m_realm_key;
|
||||||
bool m_cache = false;
|
bool m_cache = false;
|
||||||
};
|
};
|
||||||
|
@ -306,7 +306,7 @@ static void check_read_write(Realm *realm)
|
|||||||
|
|
||||||
void Realm::verify_thread() const
|
void Realm::verify_thread() const
|
||||||
{
|
{
|
||||||
if (m_thread_id != std::this_thread::get_id()) {
|
if (m_thread_id != util::get_thread_id()) {
|
||||||
throw IncorrectThreadException();
|
throw IncorrectThreadException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,9 +19,11 @@
|
|||||||
#ifndef REALM_REALM_HPP
|
#ifndef REALM_REALM_HPP
|
||||||
#define REALM_REALM_HPP
|
#define REALM_REALM_HPP
|
||||||
|
|
||||||
|
#include "util/thread_id.hpp"
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <thread>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace realm {
|
namespace realm {
|
||||||
@ -128,7 +130,7 @@ namespace realm {
|
|||||||
bool compact();
|
bool compact();
|
||||||
void write_copy(StringData path, BinaryData encryption_key);
|
void write_copy(StringData path, BinaryData encryption_key);
|
||||||
|
|
||||||
std::thread::id thread_id() const { return m_thread_id; }
|
thread_id_t thread_id() const { return m_thread_id; }
|
||||||
void verify_thread() const;
|
void verify_thread() const;
|
||||||
void verify_in_write() const;
|
void verify_in_write() const;
|
||||||
|
|
||||||
@ -174,7 +176,7 @@ namespace realm {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Config m_config;
|
Config m_config;
|
||||||
std::thread::id m_thread_id = std::this_thread::get_id();
|
thread_id_t m_thread_id = util::get_thread_id();
|
||||||
bool m_auto_refresh = true;
|
bool m_auto_refresh = true;
|
||||||
|
|
||||||
std::unique_ptr<Replication> m_history;
|
std::unique_ptr<Replication> m_history;
|
||||||
|
@ -134,4 +134,4 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // REALM_ASYNC_QUERY_HPP
|
#endif // REALM_ATOMIC_SHARED_PTR_HPP
|
||||||
|
37
src/object-store/src/util/thread_id.cpp
Normal file
37
src/object-store/src/util/thread_id.cpp
Normal file
@ -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;
|
||||||
|
}
|
37
src/object-store/src/util/thread_id.hpp
Normal file
37
src/object-store/src/util/thread_id.hpp
Normal file
@ -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.
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef REALM_THREAD_ID_HPP
|
||||||
|
#define REALM_THREAD_ID_HPP
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
namespace realm {
|
||||||
|
|
||||||
|
using thread_id_t = std::size_t;
|
||||||
|
|
||||||
|
namespace util {
|
||||||
|
|
||||||
|
// Since std::thread::id may be reused after a thread is destroyed, we use
|
||||||
|
// an atomically incremented, thread-local identifier instead.
|
||||||
|
thread_id_t get_thread_id();
|
||||||
|
|
||||||
|
} // namespace util
|
||||||
|
} // namespace realm
|
||||||
|
|
||||||
|
#endif // REALM_THREAD_ID_HPP
|
79
src/object-store/src/util/thread_local.hpp
Normal file
79
src/object-store/src/util/thread_local.hpp
Normal file
@ -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 !defined(__clang__) || REALM_HAVE_CLANG_FEATURE(tls) || REALM_HAVE_CLANG_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…
x
Reference in New Issue
Block a user