Reduce the scope of class friendships
This commit is contained in:
parent
13e1054553
commit
8c4f2a4f30
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,22 +63,33 @@ 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))
|
||||||
{
|
{
|
||||||
try {
|
open_with_config(m_config, m_history, m_shared_group, m_read_only_group);
|
||||||
if (m_config.read_only) {
|
|
||||||
m_read_only_group = std::make_unique<Group>(m_config.path, m_config.encryption_key.data(), Group::mode_ReadOnly);
|
if (m_read_only_group) {
|
||||||
m_group = m_read_only_group.get();
|
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 (config.read_only) {
|
||||||
|
read_only_group = std::make_unique<Group>(config.path, config.encryption_key.data(), Group::mode_ReadOnly);
|
||||||
|
}
|
||||||
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.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in New Issue