From 8c4f2a4f309639e475403d99ee42a15bc452112d Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Thu, 10 Dec 2015 14:29:13 -0800 Subject: [PATCH] Reduce the scope of class friendships --- src/impl/async_query.cpp | 6 +++--- src/impl/realm_coordinator.cpp | 32 +++++++++++++++++--------------- src/shared_realm.cpp | 29 ++++++++++++++++++++--------- src/shared_realm.hpp | 18 +++++++++++++++--- 4 files changed, 55 insertions(+), 30 deletions(-) diff --git a/src/impl/async_query.cpp b/src/impl/async_query.cpp index 097ef13b..75831434 100644 --- a/src/impl/async_query.cpp +++ b/src/impl/async_query.cpp @@ -28,10 +28,10 @@ AsyncQuery::AsyncQuery(Results& target) : m_target_results(&target) , m_realm(target.get_realm()) , m_sort(target.get_sort()) -, m_version(m_realm->m_shared_group->get_version_of_current_transaction()) +, m_version(Realm::Internal::get_shared_group(*m_realm).get_version_of_current_transaction()) { Query q = target.get_query(); - m_query_handover = m_realm->m_shared_group->export_for_handover(q, MutableSourcePayload::Move); + m_query_handover = Realm::Internal::get_shared_group(*m_realm).export_for_handover(q, MutableSourcePayload::Move); } size_t AsyncQuery::add_callback(std::function callback) @@ -176,7 +176,7 @@ void AsyncQuery::deliver(SharedGroup& sg, std::exception_ptr err) REALM_ASSERT(!m_query_handover); - auto realm_version = m_realm->m_shared_group->get_version_of_current_transaction(); + auto realm_version = Realm::Internal::get_shared_group(*m_realm).get_version_of_current_transaction(); if (m_version != realm_version) { // Realm version can be newer if a commit was made on our thread or the // user manually called refresh(), or older if a commit was made on a diff --git a/src/impl/realm_coordinator.cpp b/src/impl/realm_coordinator.cpp index 1644465f..29abf8ee 100644 --- a/src/impl/realm_coordinator.cpp +++ b/src/impl/realm_coordinator.cpp @@ -214,11 +214,9 @@ void RealmCoordinator::pin_version(uint_fast64_t version, uint_fast32_t index) SharedGroup::VersionID versionid(version, index); if (!m_advancer_sg) { try { - // Use a temporary Realm instance to open the shared group to reuse - // the error handling there - Realm tmp(m_config); - m_advancer_history = std::move(tmp.m_history); - m_advancer_sg = std::move(tmp.m_shared_group); + std::unique_ptr read_only_group; + Realm::open_with_config(m_config, m_advancer_history, m_advancer_sg, read_only_group); + REALM_ASSERT(!read_only_group); m_advancer_sg->begin_read(versionid); } catch (...) { @@ -242,7 +240,7 @@ void RealmCoordinator::pin_version(uint_fast64_t version, uint_fast32_t index) void RealmCoordinator::register_query(std::shared_ptr query) { auto version = query->version(); - auto& self = *query->get_realm().m_coordinator; + auto& self = Realm::Internal::get_coordinator(query->get_realm()); { std::lock_guard lock(self.m_query_mutex); self.pin_version(version.version, version.index); @@ -266,7 +264,7 @@ void RealmCoordinator::unregister_query(AsyncQuery& query) return false; }; - auto& self = *query.get_realm().m_coordinator; + auto& self = Realm::Internal::get_coordinator(query.get_realm()); std::lock_guard lock(self.m_query_mutex); if (swap_remove(self.m_queries)) { // Make sure we aren't holding on to read versions needlessly if there @@ -348,9 +346,9 @@ void RealmCoordinator::open_helper_shared_group() { if (!m_query_sg) { try { - Realm tmp(m_config); - m_query_history = std::move(tmp.m_history); - m_query_sg = std::move(tmp.m_shared_group); + std::unique_ptr read_only_group; + Realm::open_with_config(m_config, m_query_history, m_query_sg, read_only_group); + REALM_ASSERT(!read_only_group); m_query_sg->begin_read(); } catch (...) { @@ -412,6 +410,9 @@ void RealmCoordinator::advance_to_ready(Realm& realm) { decltype(m_queries) queries; + auto& sg = Realm::Internal::get_shared_group(realm); + auto& history = Realm::Internal::get_history(realm); + std::lock_guard lock(m_query_version_mutex); { std::lock_guard lock(m_query_mutex); @@ -426,20 +427,20 @@ void RealmCoordinator::advance_to_ready(Realm& realm) // no untargeted async queries; just advance to latest if (version.version == 0) { - transaction::advance(*realm.m_shared_group, *realm.m_history, realm.m_binding_context.get()); + transaction::advance(sg, history, realm.m_binding_context.get()); return; } // async results are out of date; ignore - else if (version < realm.m_shared_group->get_version_of_current_transaction()) { + else if (version < sg.get_version_of_current_transaction()) { return; } - transaction::advance(*realm.m_shared_group, *realm.m_history, realm.m_binding_context.get(), version); + transaction::advance(sg, history, realm.m_binding_context.get(), version); queries = m_queries; } for (auto& query : queries) { - query->deliver(*realm.m_shared_group, m_async_error); + query->deliver(sg, m_async_error); } } @@ -451,8 +452,9 @@ void RealmCoordinator::process_available_async(Realm& realm) queries = m_queries; } + auto& sg = Realm::Internal::get_shared_group(realm); std::lock_guard lock(m_query_version_mutex); for (auto& query : queries) { - query->deliver(*realm.m_shared_group, m_async_error); + query->deliver(sg, m_async_error); } } diff --git a/src/shared_realm.cpp b/src/shared_realm.cpp index 71e9538e..ce435ab7 100644 --- a/src/shared_realm.cpp +++ b/src/shared_realm.cpp @@ -62,23 +62,34 @@ Realm::Config& Realm::Config::operator=(realm::Realm::Config const& c) Realm::Realm(Config config) : m_config(std::move(config)) +{ + open_with_config(m_config, m_history, m_shared_group, m_read_only_group); + + if (m_read_only_group) { + m_group = m_read_only_group.get(); + } +} + +void Realm::open_with_config(const Config& config, + std::unique_ptr& history, + std::unique_ptr& shared_group, + std::unique_ptr& read_only_group) { try { - if (m_config.read_only) { - m_read_only_group = std::make_unique(m_config.path, m_config.encryption_key.data(), Group::mode_ReadOnly); - m_group = m_read_only_group.get(); + if (config.read_only) { + read_only_group = std::make_unique(config.path, config.encryption_key.data(), Group::mode_ReadOnly); } else { - m_history = realm::make_client_history(m_config.path, m_config.encryption_key.data()); - SharedGroup::DurabilityLevel durability = m_config.in_memory ? SharedGroup::durability_MemOnly : + history = realm::make_client_history(config.path, config.encryption_key.data()); + SharedGroup::DurabilityLevel durability = config.in_memory ? SharedGroup::durability_MemOnly : SharedGroup::durability_Full; - m_shared_group = std::make_unique(*m_history, durability, m_config.encryption_key.data(), !m_config.disable_format_upgrade); + shared_group = std::make_unique(*history, durability, config.encryption_key.data(), !config.disable_format_upgrade); } } catch (util::File::PermissionDenied const& ex) { throw RealmFileException(RealmFileException::Kind::PermissionDenied, ex.get_path(), "Unable to open a realm at path '" + ex.get_path() + - "'. Please use a path where your app has " + (m_config.read_only ? "read" : "read-write") + " permissions."); + "'. Please use a path where your app has " + (config.read_only ? "read" : "read-write") + " permissions."); } catch (util::File::Exists const& ex) { throw RealmFileException(RealmFileException::Kind::Exists, ex.get_path(), @@ -93,12 +104,12 @@ Realm::Realm(Config config) "Unable to open a realm at path '" + ex.get_path() + "'"); } catch (IncompatibleLockFile const& ex) { - throw RealmFileException(RealmFileException::Kind::IncompatibleLockFile, m_config.path, + throw RealmFileException(RealmFileException::Kind::IncompatibleLockFile, config.path, "Realm file is currently open in another process " "which cannot share access with this process. All processes sharing a single file must be the same architecture."); } catch (FileFormatUpgradeRequired const& ex) { - throw RealmFileException(RealmFileException::Kind::FormatUpgradeRequired, m_config.path, + throw RealmFileException(RealmFileException::Kind::FormatUpgradeRequired, config.path, "The Realm file format must be allowed to be upgraded " "in order to proceed."); } diff --git a/src/shared_realm.hpp b/src/shared_realm.hpp index fdf064b8..422af4bf 100644 --- a/src/shared_realm.hpp +++ b/src/shared_realm.hpp @@ -116,6 +116,21 @@ namespace realm { void init(std::shared_ptr<_impl::RealmCoordinator> coordinator); Realm(Config config); + // Give AsyncQuery direct access to the shared group as it needs it to + // call the handover functions + class Internal { + friend class _impl::AsyncQuery; + friend class _impl::RealmCoordinator; + static SharedGroup& get_shared_group(Realm& realm) { return *realm.m_shared_group; } + static ClientHistory& get_history(Realm& realm) { return *realm.m_history; } + static _impl::RealmCoordinator& get_coordinator(Realm& realm) { return *realm.m_coordinator; } + }; + + static void open_with_config(const Config& config, + std::unique_ptr& history, + std::unique_ptr& shared_group, + std::unique_ptr& read_only_group); + private: Config m_config; std::thread::id m_thread_id = std::this_thread::get_id(); @@ -135,9 +150,6 @@ namespace realm { // FIXME private Group *read_group(); - - friend class _impl::AsyncQuery; - friend class _impl::RealmCoordinator; }; class RealmFileException : public std::runtime_error {