Skip to content

Commit d3fa720

Browse files
Unregister SyncSession callbacks when SyncManager is destroyed
1 parent 2c3c3a0 commit d3fa720

File tree

3 files changed

+49
-2
lines changed

3 files changed

+49
-2
lines changed

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

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,17 @@ SyncSession::SyncSession(Private, SyncClient& client, std::shared_ptr<DB> db, co
402402

403403
void SyncSession::detach_from_sync_manager()
404404
{
405+
// Unregister all callbacks when the App and SyncManager are destroyed.
406+
{
407+
util::CheckedLockGuard lk(m_state_mutex);
408+
m_completion_callbacks.clear();
409+
}
410+
{
411+
util::CheckedLockGuard lk(m_connection_state_mutex);
412+
m_connection_change_notifier.remove_callbacks();
413+
}
414+
m_progress_notifier.unregister_callbacks();
415+
405416
shutdown_and_wait();
406417
util::CheckedLockGuard lk(m_state_mutex);
407418
m_sync_manager = nullptr;
@@ -1555,6 +1566,14 @@ void SyncProgressNotifier::unregister_callback(uint64_t token)
15551566
m_packages.erase(token);
15561567
}
15571568

1569+
void SyncProgressNotifier::unregister_callbacks()
1570+
{
1571+
std::lock_guard<std::mutex> lock(m_mutex);
1572+
m_packages.clear();
1573+
m_current_progress.reset();
1574+
m_local_transaction_version = 0;
1575+
}
1576+
15581577
void SyncProgressNotifier::update(uint64_t downloaded, uint64_t downloadable, uint64_t uploaded, uint64_t uploadable,
15591578
uint64_t snapshot_version, double download_estimate, double upload_estimate,
15601579
int64_t query_version)
@@ -1662,6 +1681,14 @@ void SyncSession::ConnectionChangeNotifier::remove_callback(uint64_t token)
16621681
}
16631682
}
16641683

1684+
void SyncSession::ConnectionChangeNotifier::remove_callbacks()
1685+
{
1686+
std::lock_guard<std::mutex> lock(m_callback_mutex);
1687+
m_callbacks.clear();
1688+
m_callback_count = -1;
1689+
m_callback_index = -1;
1690+
}
1691+
16651692
void SyncSession::ConnectionChangeNotifier::invoke_callbacks(ConnectionState old_state, ConnectionState new_state)
16661693
{
16671694
std::unique_lock lock(m_callback_mutex);

src/realm/object-store/sync/sync_session.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ class SyncProgressNotifier {
5757
uint64_t register_callback(std::function<ProgressNotifierCallback>, NotifierType direction, bool is_streaming,
5858
int64_t pending_query_version);
5959
void unregister_callback(uint64_t);
60+
void unregister_callbacks();
6061

6162
void set_local_version(uint64_t);
6263
void update(uint64_t downloaded, uint64_t downloadable, uint64_t uploaded, uint64_t uploadable,
@@ -368,6 +369,7 @@ class SyncSession : public std::enable_shared_from_this<SyncSession> {
368369
public:
369370
uint64_t add_callback(std::function<ConnectionStateChangeCallback> callback);
370371
void remove_callback(uint64_t token);
372+
void remove_callbacks();
371373
void invoke_callbacks(ConnectionState old_state, ConnectionState new_state);
372374

373375
private:
@@ -394,8 +396,6 @@ class SyncSession : public std::enable_shared_from_this<SyncSession> {
394396
}
395397
// }
396398

397-
std::shared_ptr<SyncManager> sync_manager() const REQUIRES(!m_state_mutex);
398-
399399
static util::UniqueFunction<void(std::optional<app::AppError>)>
400400
handle_refresh(const std::shared_ptr<SyncSession>&, bool);
401401

test/object-store/sync/session/connection_change_notifications.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,4 +117,24 @@ TEST_CASE("sync: Connection state changes", "[sync][session][connection change]"
117117
REQUIRE(listener1_call_cnt == 1); // Only called once before unregister
118118
REQUIRE(listener2_called);
119119
}
120+
121+
SECTION("Callback not invoked when SyncSession is detached from SyncManager") {
122+
auto session = sync_session(
123+
user, "/connection-state-changes-1", [](auto, auto) {}, SyncSessionStopPolicy::AfterChangesUploaded);
124+
125+
EventLoop::main().run_until([&] {
126+
return sessions_are_active(*session);
127+
});
128+
EventLoop::main().run_until([&] {
129+
return sessions_are_connected(*session);
130+
});
131+
132+
bool listener_called = false;
133+
session->register_connection_change_callback([&](SyncSession::ConnectionState, SyncSession::ConnectionState) {
134+
listener_called = true;
135+
});
136+
137+
session->detach_from_sync_manager();
138+
REQUIRE_FALSE(listener_called);
139+
}
120140
}

0 commit comments

Comments
 (0)