Reduce the scope of class friendships

This commit is contained in:
Thomas Goyne 2015-12-10 14:29:13 -08:00
parent 13e1054553
commit 8c4f2a4f30
4 changed files with 55 additions and 30 deletions

View File

@ -28,10 +28,10 @@ AsyncQuery::AsyncQuery(Results& target)
: m_target_results(&target) : m_target_results(&target)
, m_realm(target.get_realm()) , m_realm(target.get_realm())
, m_sort(target.get_sort()) , 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(); 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<void (std::exception_ptr)> callback) size_t AsyncQuery::add_callback(std::function<void (std::exception_ptr)> callback)
@ -176,7 +176,7 @@ void AsyncQuery::deliver(SharedGroup& sg, std::exception_ptr err)
REALM_ASSERT(!m_query_handover); 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) { if (m_version != realm_version) {
// Realm version can be newer if a commit was made on our thread or the // 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 // user manually called refresh(), or older if a commit was made on a

View File

@ -214,11 +214,9 @@ void RealmCoordinator::pin_version(uint_fast64_t version, uint_fast32_t index)
SharedGroup::VersionID versionid(version, index); SharedGroup::VersionID versionid(version, index);
if (!m_advancer_sg) { if (!m_advancer_sg) {
try { try {
// Use a temporary Realm instance to open the shared group to reuse std::unique_ptr<Group> read_only_group;
// the error handling there Realm::open_with_config(m_config, m_advancer_history, m_advancer_sg, read_only_group);
Realm tmp(m_config); REALM_ASSERT(!read_only_group);
m_advancer_history = std::move(tmp.m_history);
m_advancer_sg = std::move(tmp.m_shared_group);
m_advancer_sg->begin_read(versionid); m_advancer_sg->begin_read(versionid);
} }
catch (...) { catch (...) {
@ -242,7 +240,7 @@ void RealmCoordinator::pin_version(uint_fast64_t version, uint_fast32_t index)
void RealmCoordinator::register_query(std::shared_ptr<AsyncQuery> query) void RealmCoordinator::register_query(std::shared_ptr<AsyncQuery> query)
{ {
auto version = query->version(); auto version = query->version();
auto& self = *query->get_realm().m_coordinator; auto& self = Realm::Internal::get_coordinator(query->get_realm());
{ {
std::lock_guard<std::mutex> lock(self.m_query_mutex); std::lock_guard<std::mutex> lock(self.m_query_mutex);
self.pin_version(version.version, version.index); self.pin_version(version.version, version.index);
@ -266,7 +264,7 @@ void RealmCoordinator::unregister_query(AsyncQuery& query)
return false; return false;
}; };
auto& self = *query.get_realm().m_coordinator; auto& self = Realm::Internal::get_coordinator(query.get_realm());
std::lock_guard<std::mutex> lock(self.m_query_mutex); std::lock_guard<std::mutex> lock(self.m_query_mutex);
if (swap_remove(self.m_queries)) { if (swap_remove(self.m_queries)) {
// Make sure we aren't holding on to read versions needlessly if there // 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) { if (!m_query_sg) {
try { try {
Realm tmp(m_config); std::unique_ptr<Group> read_only_group;
m_query_history = std::move(tmp.m_history); Realm::open_with_config(m_config, m_query_history, m_query_sg, read_only_group);
m_query_sg = std::move(tmp.m_shared_group); REALM_ASSERT(!read_only_group);
m_query_sg->begin_read(); m_query_sg->begin_read();
} }
catch (...) { catch (...) {
@ -412,6 +410,9 @@ void RealmCoordinator::advance_to_ready(Realm& realm)
{ {
decltype(m_queries) queries; decltype(m_queries) queries;
auto& sg = Realm::Internal::get_shared_group(realm);
auto& history = Realm::Internal::get_history(realm);
std::lock_guard<std::mutex> lock(m_query_version_mutex); std::lock_guard<std::mutex> lock(m_query_version_mutex);
{ {
std::lock_guard<std::mutex> lock(m_query_mutex); std::lock_guard<std::mutex> lock(m_query_mutex);
@ -426,20 +427,20 @@ void RealmCoordinator::advance_to_ready(Realm& realm)
// no untargeted async queries; just advance to latest // no untargeted async queries; just advance to latest
if (version.version == 0) { 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; return;
} }
// async results are out of date; ignore // 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; 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; queries = m_queries;
} }
for (auto& query : 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; queries = m_queries;
} }
auto& sg = Realm::Internal::get_shared_group(realm);
std::lock_guard<std::mutex> lock(m_query_version_mutex); std::lock_guard<std::mutex> lock(m_query_version_mutex);
for (auto& query : queries) { for (auto& query : queries) {
query->deliver(*realm.m_shared_group, m_async_error); query->deliver(sg, m_async_error);
} }
} }

View File

@ -62,23 +62,34 @@ Realm::Config& Realm::Config::operator=(realm::Realm::Config const& c)
Realm::Realm(Config config) Realm::Realm(Config config)
: m_config(std::move(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<ClientHistory>& history,
std::unique_ptr<SharedGroup>& shared_group,
std::unique_ptr<Group>& read_only_group)
{ {
try { try {
if (m_config.read_only) { if (config.read_only) {
m_read_only_group = std::make_unique<Group>(m_config.path, m_config.encryption_key.data(), Group::mode_ReadOnly); read_only_group = std::make_unique<Group>(config.path, config.encryption_key.data(), Group::mode_ReadOnly);
m_group = m_read_only_group.get();
} }
else { else {
m_history = realm::make_client_history(m_config.path, m_config.encryption_key.data()); history = realm::make_client_history(config.path, config.encryption_key.data());
SharedGroup::DurabilityLevel durability = m_config.in_memory ? SharedGroup::durability_MemOnly : SharedGroup::DurabilityLevel durability = config.in_memory ? SharedGroup::durability_MemOnly :
SharedGroup::durability_Full; SharedGroup::durability_Full;
m_shared_group = std::make_unique<SharedGroup>(*m_history, durability, m_config.encryption_key.data(), !m_config.disable_format_upgrade); shared_group = std::make_unique<SharedGroup>(*history, durability, config.encryption_key.data(), !config.disable_format_upgrade);
} }
} }
catch (util::File::PermissionDenied const& ex) { catch (util::File::PermissionDenied const& ex) {
throw RealmFileException(RealmFileException::Kind::PermissionDenied, ex.get_path(), throw RealmFileException(RealmFileException::Kind::PermissionDenied, ex.get_path(),
"Unable to open a realm at path '" + 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) { catch (util::File::Exists const& ex) {
throw RealmFileException(RealmFileException::Kind::Exists, ex.get_path(), 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() + "'"); "Unable to open a realm at path '" + ex.get_path() + "'");
} }
catch (IncompatibleLockFile const& ex) { 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 " "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."); "which cannot share access with this process. All processes sharing a single file must be the same architecture.");
} }
catch (FileFormatUpgradeRequired const& ex) { 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 " "The Realm file format must be allowed to be upgraded "
"in order to proceed."); "in order to proceed.");
} }

View File

@ -116,6 +116,21 @@ namespace realm {
void init(std::shared_ptr<_impl::RealmCoordinator> coordinator); void init(std::shared_ptr<_impl::RealmCoordinator> coordinator);
Realm(Config config); 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<ClientHistory>& history,
std::unique_ptr<SharedGroup>& shared_group,
std::unique_ptr<Group>& read_only_group);
private: private:
Config m_config; Config m_config;
std::thread::id m_thread_id = std::this_thread::get_id(); std::thread::id m_thread_id = std::this_thread::get_id();
@ -135,9 +150,6 @@ namespace realm {
// FIXME private // FIXME private
Group *read_group(); Group *read_group();
friend class _impl::AsyncQuery;
friend class _impl::RealmCoordinator;
}; };
class RealmFileException : public std::runtime_error { class RealmFileException : public std::runtime_error {