Skip to content

Commit f66e24d

Browse files
authored
Merge pull request #7576 from realm/tg/multi-process-launch-actions
RCORE-1900 Make "next launch" metadata actions multiprocess-safe
2 parents fb46803 + b2a419b commit f66e24d

File tree

18 files changed

+491
-369
lines changed

18 files changed

+491
-369
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
### Enhancements
44
* <New feature description> (PR [#????](https://github.com/realm/realm-core/pull/????))
5-
* None.
5+
* "Next launch" metadata file actions are now performed in a multi-process safe manner ([#7576](https://github.com/realm/realm-core/pull/7576)).
66

77
### Fixed
88
* <How do the end-user experience this issue? what was the impact?> ([#????](https://github.com/realm/realm-core/issues/????), since v?.?.?)

src/realm/db.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2860,20 +2860,27 @@ DBRef DB::create(BinaryData buffer, bool take_ownership) NO_THREAD_SAFETY_ANALYS
28602860
return retval;
28612861
}
28622862

2863-
void DB::claim_sync_agent()
2863+
bool DB::try_claim_sync_agent()
28642864
{
28652865
REALM_ASSERT(is_attached());
2866-
std::unique_lock<InterprocessMutex> lock(m_controlmutex);
2866+
std::lock_guard lock(m_controlmutex);
28672867
if (m_info->sync_agent_present)
2868-
throw MultipleSyncAgents{};
2868+
return false;
28692869
m_info->sync_agent_present = 1; // Set to true
28702870
m_is_sync_agent = true;
2871+
return true;
2872+
}
2873+
2874+
void DB::claim_sync_agent()
2875+
{
2876+
if (!try_claim_sync_agent())
2877+
throw MultipleSyncAgents{};
28712878
}
28722879

28732880
void DB::release_sync_agent()
28742881
{
28752882
REALM_ASSERT(is_attached());
2876-
std::unique_lock<InterprocessMutex> lock(m_controlmutex);
2883+
std::lock_guard lock(m_controlmutex);
28772884
if (!m_is_sync_agent)
28782885
return;
28792886
REALM_ASSERT(m_info->sync_agent_present);

src/realm/db.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,7 @@ class DB : public std::enable_shared_from_this<DB> {
432432
/// Mark this DB as the sync agent for the file.
433433
/// \throw MultipleSyncAgents if another DB is already the sync agent.
434434
void claim_sync_agent();
435+
bool try_claim_sync_agent();
435436
void release_sync_agent();
436437

437438
/// Returns true if there are threads waiting to acquire the write lock, false otherwise.

src/realm/object-store/impl/realm_coordinator.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,11 @@ class RealmCoordinator : public std::enable_shared_from_this<RealmCoordinator>,
228228
return m_audit_context.get();
229229
}
230230

231+
bool try_claim_sync_agent()
232+
{
233+
return m_db->try_claim_sync_agent();
234+
}
235+
231236
private:
232237
friend Realm::Internal;
233238
Realm::Config m_config;

src/realm/object-store/sync/app.cpp

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -715,12 +715,11 @@ void App::get_profile(const std::shared_ptr<User>& user,
715715
identities.push_back({get<std::string>(doc, "id"), get<std::string>(doc, "provider_type")});
716716
}
717717

718-
if (auto data = m_metadata_store->get_user(user->user_id())) {
719-
data->identities = std::move(identities);
720-
data->profile = UserProfile(get<BsonDocument>(profile_json, "data"));
721-
m_metadata_store->update_user(user->user_id(), *data);
722-
user->update_backing_data(std::move(data));
723-
}
718+
m_metadata_store->update_user(user->user_id(), [&](auto& data) {
719+
data.identities = std::move(identities);
720+
data.profile = UserProfile(get<BsonDocument>(profile_json, "data"));
721+
user->update_backing_data(data); // FIXME
722+
});
724723
}
725724
catch (const AppError& err) {
726725
return completion(nullptr, err);
@@ -812,12 +811,11 @@ void App::log_in_with_credentials(const AppCredentials& credentials, const std::
812811
try {
813812
auto json = parse<BsonDocument>(response.body);
814813
if (linking_user) {
815-
if (auto user_data = m_metadata_store->get_user(linking_user->user_id())) {
816-
user_data->access_token = RealmJWT(get<std::string>(json, "access_token"));
817-
// maybe a callback for this?
818-
m_metadata_store->update_user(linking_user->user_id(), *user_data);
819-
linking_user->update_backing_data(std::move(user_data));
820-
}
814+
m_metadata_store->update_user(linking_user->user_id(), [&](auto& data) {
815+
data.access_token = RealmJWT(get<std::string>(json, "access_token"));
816+
// FIXME: should be powered by callback
817+
linking_user->update_backing_data(data);
818+
});
821819
}
822820
else {
823821
auto user_id = get<std::string>(json, "user_id");
@@ -1338,11 +1336,10 @@ void App::refresh_access_token(const std::shared_ptr<User>& user, bool update_lo
13381336
try {
13391337
auto json = parse<BsonDocument>(response.body);
13401338
RealmJWT access_token{get<std::string>(json, "access_token")};
1341-
if (auto data = self->m_metadata_store->get_user(user->user_id())) {
1342-
data->access_token = access_token;
1343-
self->m_metadata_store->update_user(user->user_id(), *data);
1344-
user->update_backing_data(std::move(data));
1345-
}
1339+
self->m_metadata_store->update_user(user->user_id(), [&](auto& data) {
1340+
data.access_token = access_token;
1341+
user->update_backing_data(data);
1342+
});
13461343
}
13471344
catch (AppError& err) {
13481345
return completion(std::move(err));

src/realm/object-store/sync/async_open_task.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <realm/object-store/impl/realm_coordinator.hpp>
2424
#include <realm/object-store/sync/sync_session.hpp>
2525
#include <realm/object-store/thread_safe_reference.hpp>
26+
#include <realm/object-store/util/scheduler.hpp>
2627

2728
namespace realm {
2829

@@ -126,7 +127,7 @@ void AsyncOpenTask::wait_for_bootstrap_or_complete(AsyncOpenCallback&& callback,
126127

127128
SharedRealm shared_realm;
128129
try {
129-
shared_realm = coordinator->get_realm(nullptr, m_db_first_open);
130+
shared_realm = coordinator->get_realm(util::Scheduler::make_dummy(), m_db_first_open);
130131
}
131132
catch (...) {
132133
async_open_complete(std::move(callback), coordinator, exception_to_status());

0 commit comments

Comments
 (0)