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_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<void (std::exception_ptr)> 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

View File

@ -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<Group> 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<AsyncQuery> query)
{
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);
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<std::mutex> 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<Group> 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<std::mutex> lock(m_query_version_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
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<std::mutex> lock(m_query_version_mutex);
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)
: 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 {
if (m_config.read_only) {
m_read_only_group = std::make_unique<Group>(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<Group>(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<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) {
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.");
}

View File

@ -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<ClientHistory>& history,
std::unique_ptr<SharedGroup>& shared_group,
std::unique_ptr<Group>& 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 {