diff --git a/src/RealmJS.xcodeproj/project.pbxproj b/src/RealmJS.xcodeproj/project.pbxproj index 97e699c6..7c77477c 100644 --- a/src/RealmJS.xcodeproj/project.pbxproj +++ b/src/RealmJS.xcodeproj/project.pbxproj @@ -189,6 +189,7 @@ F620F0571CB766DA0082977B /* node_init.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = node_init.cpp; sourceTree = ""; }; F620F0591CB7B4C80082977B /* js_object_accessor.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = js_object_accessor.hpp; sourceTree = ""; }; 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 = ""; }; F6267BC91CADC30000AC36B1 /* js_util.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = js_util.hpp; sourceTree = ""; }; F6267BCA1CADC49200AC36B1 /* node_dummy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = node_dummy.cpp; sourceTree = ""; }; F62BF8FB1CAC71780022BCDC /* libRealmNode.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libRealmNode.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -363,6 +364,7 @@ 02E008D11D10AB1B00F3AA37 /* atomic_shared_ptr.hpp */, 02E008D21D10AB1B00F3AA37 /* format.cpp */, 02E008D31D10AB1B00F3AA37 /* format.hpp */, + F6242B291D08EE9600BE1E03 /* thread_id.hpp */, ); name = util; path = src/util; diff --git a/src/object-store/src/impl/weak_realm_notifier_base.hpp b/src/object-store/src/impl/weak_realm_notifier_base.hpp index b72636fa..ab19c6ae 100644 --- a/src/object-store/src/impl/weak_realm_notifier_base.hpp +++ b/src/object-store/src/impl/weak_realm_notifier_base.hpp @@ -19,8 +19,9 @@ #ifndef REALM_WEAK_REALM_NOTIFIER_BASE_HPP #define REALM_WEAK_REALM_NOTIFIER_BASE_HPP +#include "util/thread_id.hpp" + #include -#include namespace realm { class Realm; @@ -48,11 +49,11 @@ public: // Is this a WeakRealmNotifierBase for the given Realm instance? 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: std::weak_ptr 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; bool m_cache = false; }; diff --git a/src/object-store/src/shared_realm.cpp b/src/object-store/src/shared_realm.cpp index 3d603225..af6ac3af 100644 --- a/src/object-store/src/shared_realm.cpp +++ b/src/object-store/src/shared_realm.cpp @@ -306,7 +306,7 @@ static void check_read_write(Realm *realm) void Realm::verify_thread() const { - if (m_thread_id != std::this_thread::get_id()) { + if (m_thread_id != util::get_thread_id()) { throw IncorrectThreadException(); } } diff --git a/src/object-store/src/shared_realm.hpp b/src/object-store/src/shared_realm.hpp index 50041642..e6e0b5a7 100644 --- a/src/object-store/src/shared_realm.hpp +++ b/src/object-store/src/shared_realm.hpp @@ -19,9 +19,11 @@ #ifndef REALM_REALM_HPP #define REALM_REALM_HPP +#include "util/thread_id.hpp" + +#include #include #include -#include #include namespace realm { @@ -128,7 +130,7 @@ namespace realm { bool compact(); 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_in_write() const; @@ -174,7 +176,7 @@ namespace realm { private: 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; std::unique_ptr m_history; diff --git a/src/object-store/src/util/atomic_shared_ptr.hpp b/src/object-store/src/util/atomic_shared_ptr.hpp index 0ec541e7..1d07e022 100644 --- a/src/object-store/src/util/atomic_shared_ptr.hpp +++ b/src/object-store/src/util/atomic_shared_ptr.hpp @@ -134,4 +134,4 @@ private: } } -#endif // REALM_ASYNC_QUERY_HPP +#endif // REALM_ATOMIC_SHARED_PTR_HPP diff --git a/src/object-store/src/util/thread_id.hpp b/src/object-store/src/util/thread_id.hpp new file mode 100644 index 00000000..e1121e2a --- /dev/null +++ b/src/object-store/src/util/thread_id.hpp @@ -0,0 +1,48 @@ +//////////////////////////////////////////////////////////////////////////// +// +// 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 + +#include + +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. +inline thread_id_t get_thread_id() { + static std::atomic id_counter; + static REALM_THREAD_LOCAL thread_id_t thread_id = 0; + + if (REALM_UNLIKELY(!thread_id)) { + thread_id = ++id_counter; + } + + return thread_id; +} + +} // namespace util +} // namespace realm + +#endif // REALM_THREAD_ID_HPP