From 7df26853f2a36da06ce62ab68fb6797d4d2285aa Mon Sep 17 00:00:00 2001 From: Nicola Cabiddu Date: Fri, 26 Aug 2022 16:14:49 +0100 Subject: [PATCH 1/6] expose async transaction realm support in the CAPI --- src/realm.h | 29 +++++++++++++- src/realm/object-store/c_api/realm.cpp | 52 +++++++++++++++++++++++++- src/realm/object-store/c_api/types.hpp | 15 ++++++++ test/object-store/c_api/c_api.cpp | 50 +++++++++++++++---------- 4 files changed, 124 insertions(+), 22 deletions(-) diff --git a/src/realm.h b/src/realm.h index ed40938f1b1..0db6343e89c 100644 --- a/src/realm.h +++ b/src/realm.h @@ -366,12 +366,16 @@ typedef enum realm_property_flags { typedef struct realm_notification_token realm_notification_token_t; typedef struct realm_callback_token realm_callback_token_t; typedef struct realm_refresh_callback_token realm_refresh_callback_token_t; +typedef struct realm_async_transaction_token realm_async_transaction_token_t; typedef struct realm_object_changes realm_object_changes_t; typedef struct realm_collection_changes realm_collection_changes_t; typedef void (*realm_on_object_change_func_t)(realm_userdata_t userdata, const realm_object_changes_t*); typedef void (*realm_on_collection_change_func_t)(realm_userdata_t userdata, const realm_collection_changes_t*); typedef void (*realm_on_realm_change_func_t)(realm_userdata_t userdata); typedef void (*realm_on_realm_refresh_func_t)(realm_userdata_t userdata); +typedef void (*realm_on_realm_async_begin_transaction_func_t)(realm_t*, realm_userdata_t userdata); +typedef void (*realm_on_realm_async_commit_transaction_funct_t)(realm_t*, realm_userdata_t userdata, + bool error, const char* desc); /** * Callback for realm schema changed notifications. @@ -1060,6 +1064,30 @@ RLM_API bool realm_commit(realm_t*); */ RLM_API bool realm_rollback(realm_t*); +/** + * start a new write transaction asynchronously for the realm passed as argument. + */ +RLM_API realm_async_transaction_token_t* realm_async_begin_transaction(realm_t* realm, + realm_on_realm_async_begin_transaction_func_t, + realm_userdata_t userdata, + realm_free_userdata_func_t userdata_free, + bool* notify_only); + +/** + * commit a transaction asynchronously for the realm passed as argument. + */ +RLM_API realm_async_transaction_token_t* realm_async_commit_transaction(realm_t* realm, + realm_on_realm_async_commit_transaction_funct_t, + realm_userdata_t userdata, + realm_free_userdata_func_t userdata_free, + bool* allow_grouping); + +/** + * Cancel the transaction referenced by the token passed as argument and set the optional boolean flag in order to inform the caller + * if the transaction was cancelled. + */ +RLM_API bool realm_async_cancel_transaction(realm_t* realm, realm_async_transaction_token_t* token, bool* cancelled); + /** * Add a callback that will be invoked every time the view of this file is updated. * @@ -3725,7 +3753,6 @@ RLM_API uint64_t realm_async_open_task_register_download_progress_notifier( realm_free_userdata_func_t userdata_free) RLM_API_NOEXCEPT; RLM_API void realm_async_open_task_unregister_download_progress_notifier(realm_async_open_task_t*, uint64_t token) RLM_API_NOEXCEPT; - /** * Get the sync session for a specific realm. * diff --git a/src/realm/object-store/c_api/realm.cpp b/src/realm/object-store/c_api/realm.cpp index b359ee77d2c..559c2d1c4b8 100644 --- a/src/realm/object-store/c_api/realm.cpp +++ b/src/realm/object-store/c_api/realm.cpp @@ -16,7 +16,6 @@ realm_refresh_callback_token::~realm_refresh_callback_token() realm::c_api::CBindingContext::get(*m_realm).realm_pending_refresh_callbacks().remove(m_token); } - namespace realm::c_api { @@ -125,7 +124,7 @@ RLM_API bool realm_is_closed(realm_t* realm) RLM_API bool realm_is_writable(const realm_t* realm) { - return (*realm)->is_in_transaction(); + return (*realm)->is_in_transaction() || (*realm)->is_in_async_transaction(); } RLM_API bool realm_close(realm_t* realm) @@ -168,6 +167,55 @@ RLM_API bool realm_rollback(realm_t* realm) }); } +RLM_API realm_async_transaction_token_t* +realm_async_begin_transaction(realm_t* realm, realm_on_realm_async_begin_transaction_func_t callback, + realm_userdata_t userdata, realm_free_userdata_func_t userdata_free, bool* notify_only) +{ + const auto notify_only_value = notify_only ? *notify_only : false; + auto cb = [realm, callback, userdata = UserdataPtr{userdata, userdata_free}]() { + callback(realm, userdata.get()); + }; + return wrap_err([&]() { + auto handle = (*realm)->async_begin_transaction(std::move(cb), notify_only_value); + return new realm_async_transaction_token_t{handle}; + }); +} + +RLM_API realm_async_transaction_token_t* +realm_async_commit_transaction(realm_t* realm, realm_on_realm_async_commit_transaction_funct_t callback, + realm_userdata_t userdata, realm_free_userdata_func_t userdata_free, + bool* allow_grouping) +{ + const auto allowing_grouping_value = allow_grouping ? *allow_grouping : false; + auto cb = [realm, callback, userdata = UserdataPtr{userdata, userdata_free}](std::exception_ptr err) { + if (err) { + try { + std::rethrow_exception(err); + } + catch (const std::exception& e) { + callback(nullptr, userdata.get(), true, e.what()); + } + } + else { + callback(realm, userdata.get(), false, nullptr); + } + }; + return wrap_err([&]() { + auto handle = (*realm)->async_commit_transaction(std::move(cb), allowing_grouping_value); + return new realm_async_transaction_token_t{handle}; + }); +} + +RLM_API bool realm_async_cancel_transaction(realm_t* realm, realm_async_transaction_token_t* token, bool* cancelled) +{ + return wrap_err([&]() { + auto res = (*realm)->async_cancel_transaction(token->token()); + if (cancelled) + *cancelled = res; + return true; + }); +} + RLM_API realm_callback_token_t* realm_add_realm_changed_callback(realm_t* realm, realm_on_realm_change_func_t callback, realm_userdata_t userdata, diff --git a/src/realm/object-store/c_api/types.hpp b/src/realm/object-store/c_api/types.hpp index 2cefc41b0db..a95ad4c2fca 100644 --- a/src/realm/object-store/c_api/types.hpp +++ b/src/realm/object-store/c_api/types.hpp @@ -501,6 +501,21 @@ struct realm_refresh_callback_token : realm_callback_token { ~realm_refresh_callback_token() override; }; +struct realm_async_transaction_token : realm::c_api::WrapC { + realm_async_transaction_token(unsigned token) + : m_token(token) + { + } + ~realm_async_transaction_token() override = default; + unsigned token() const + { + return m_token; + } + +private: + unsigned m_token; +}; + struct realm_query : realm::c_api::WrapC { realm::Query query; std::weak_ptr weak_realm; diff --git a/test/object-store/c_api/c_api.cpp b/test/object-store/c_api/c_api.cpp index 3e9aa3766e6..acc541e14b7 100644 --- a/test/object-store/c_api/c_api.cpp +++ b/test/object-store/c_api/c_api.cpp @@ -1083,31 +1083,43 @@ TEST_CASE("C API", "[c_api]") { } SECTION("realm refresh async pending") { - bool realm_refresh_callback_called = false; - // bool on_transaction_completed = false; - bool done = false; + struct TestingObj { + static TestingObj& get() + { + static TestingObj obj; + return obj; + } + bool done{false}; + bool realm_refresh_callback_called{false}; + }; + auto wait_for_done = [&]() { util::EventLoop::main().run_until([&] { - return done; + return TestingObj::get().done; }); - REQUIRE(done); + REQUIRE(TestingObj::get().done); }; - (*realm)->async_begin_transaction([&]() { - auto token = cptr(realm_add_realm_refresh_callback( - realm, - [](void* userdata) { - *reinterpret_cast(userdata) = true; - }, - &realm_refresh_callback_called, [](void*) {})); - - (*realm)->async_commit_transaction([&](std::exception_ptr) { - done = true; - }); - }); - + auto token_begin = cptr(realm_async_begin_transaction( + realm, + [](realm_t* realm, void*) { + auto token_refresh = cptr(realm_add_realm_refresh_callback( + realm, + [](void* userdata) { + *reinterpret_cast(userdata) = true; + }, + &(TestingObj::get().realm_refresh_callback_called), [](void*) {})); + + auto token_commit = cptr(realm_async_commit_transaction( + realm, + [](realm_t*, void*, bool, const char*) { + TestingObj::get().done = true; + }, + nullptr, nullptr, nullptr)); + }, + nullptr, nullptr, nullptr)); wait_for_done(); - CHECK(realm_refresh_callback_called); + CHECK(TestingObj::get().realm_refresh_callback_called); } SECTION("realm async refresh - main use case") { From 7b283ba8c6f19d4e508eb55c66dd800e37a71c35 Mon Sep 17 00:00:00 2001 From: Nicola Cabiddu Date: Fri, 26 Aug 2022 16:19:07 +0100 Subject: [PATCH 2/6] changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f94fda713a1..65db01ac9e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ * Action returned from the server in the json error messages is surfaced through the SyncError. ([PR #5690](https://github.com/realm/realm-core/pull/5690)). * `NotificationToken` grew an `unregister()` method as an alternative to destroying it or doing `token = {};` ([PR #5776](https://github.com/realm/realm-core/pull/5776)). * Expose `Obj::add_int()` in the CAPI. ([PR #5770](https://github.com/realm/realm-core/pull/5770)). +* Expose `Realm::async_begin_transaction`, `Realm::async_commit_transaction`, `Realm::async_cancel_transaction` in the CAPI.([PR 5783 #](https://github.com/realm/realm-core/pull/5783)). ### Fixed * ([#????](https://github.com/realm/realm-core/issues/????), since v?.?.?) From a54d30182b8b80e5bced62dc712aea11b5293d5b Mon Sep 17 00:00:00 2001 From: Nicola Cabiddu Date: Fri, 26 Aug 2022 16:20:27 +0100 Subject: [PATCH 3/6] fix format checks --- src/realm.h | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/realm.h b/src/realm.h index 0db6343e89c..3cb4930258c 100644 --- a/src/realm.h +++ b/src/realm.h @@ -374,8 +374,8 @@ typedef void (*realm_on_collection_change_func_t)(realm_userdata_t userdata, con typedef void (*realm_on_realm_change_func_t)(realm_userdata_t userdata); typedef void (*realm_on_realm_refresh_func_t)(realm_userdata_t userdata); typedef void (*realm_on_realm_async_begin_transaction_func_t)(realm_t*, realm_userdata_t userdata); -typedef void (*realm_on_realm_async_commit_transaction_funct_t)(realm_t*, realm_userdata_t userdata, - bool error, const char* desc); +typedef void (*realm_on_realm_async_commit_transaction_funct_t)(realm_t*, realm_userdata_t userdata, bool error, + const char* desc); /** * Callback for realm schema changed notifications. @@ -1067,24 +1067,21 @@ RLM_API bool realm_rollback(realm_t*); /** * start a new write transaction asynchronously for the realm passed as argument. */ -RLM_API realm_async_transaction_token_t* realm_async_begin_transaction(realm_t* realm, - realm_on_realm_async_begin_transaction_func_t, - realm_userdata_t userdata, - realm_free_userdata_func_t userdata_free, - bool* notify_only); +RLM_API realm_async_transaction_token_t* +realm_async_begin_transaction(realm_t* realm, realm_on_realm_async_begin_transaction_func_t, + realm_userdata_t userdata, realm_free_userdata_func_t userdata_free, bool* notify_only); /** * commit a transaction asynchronously for the realm passed as argument. */ -RLM_API realm_async_transaction_token_t* realm_async_commit_transaction(realm_t* realm, - realm_on_realm_async_commit_transaction_funct_t, - realm_userdata_t userdata, - realm_free_userdata_func_t userdata_free, - bool* allow_grouping); +RLM_API realm_async_transaction_token_t* +realm_async_commit_transaction(realm_t* realm, realm_on_realm_async_commit_transaction_funct_t, + realm_userdata_t userdata, realm_free_userdata_func_t userdata_free, + bool* allow_grouping); /** - * Cancel the transaction referenced by the token passed as argument and set the optional boolean flag in order to inform the caller - * if the transaction was cancelled. + * Cancel the transaction referenced by the token passed as argument and set the optional boolean flag in order to + * inform the caller if the transaction was cancelled. */ RLM_API bool realm_async_cancel_transaction(realm_t* realm, realm_async_transaction_token_t* token, bool* cancelled); From 650a8e054d7aa071813b44c079a0501f9fc04000 Mon Sep 17 00:00:00 2001 From: Nicola Cabiddu Date: Fri, 26 Aug 2022 17:52:05 +0100 Subject: [PATCH 4/6] code review --- src/realm.h | 19 +++++++++---------- src/realm/object-store/c_api/realm.cpp | 24 +++++++++--------------- src/realm/object-store/c_api/types.hpp | 15 --------------- test/object-store/c_api/c_api.cpp | 9 +++++---- 4 files changed, 23 insertions(+), 44 deletions(-) diff --git a/src/realm.h b/src/realm.h index 3cb4930258c..5f439d6d1ef 100644 --- a/src/realm.h +++ b/src/realm.h @@ -366,15 +366,14 @@ typedef enum realm_property_flags { typedef struct realm_notification_token realm_notification_token_t; typedef struct realm_callback_token realm_callback_token_t; typedef struct realm_refresh_callback_token realm_refresh_callback_token_t; -typedef struct realm_async_transaction_token realm_async_transaction_token_t; typedef struct realm_object_changes realm_object_changes_t; typedef struct realm_collection_changes realm_collection_changes_t; typedef void (*realm_on_object_change_func_t)(realm_userdata_t userdata, const realm_object_changes_t*); typedef void (*realm_on_collection_change_func_t)(realm_userdata_t userdata, const realm_collection_changes_t*); typedef void (*realm_on_realm_change_func_t)(realm_userdata_t userdata); typedef void (*realm_on_realm_refresh_func_t)(realm_userdata_t userdata); -typedef void (*realm_on_realm_async_begin_transaction_func_t)(realm_t*, realm_userdata_t userdata); -typedef void (*realm_on_realm_async_commit_transaction_funct_t)(realm_t*, realm_userdata_t userdata, bool error, +typedef void (*realm_async_begin_write_func_t)(realm_t*, realm_userdata_t userdata); +typedef void (*realm_async_commit_func_t)(realm_t*, realm_userdata_t userdata, bool error, const char* desc); /** @@ -1067,23 +1066,23 @@ RLM_API bool realm_rollback(realm_t*); /** * start a new write transaction asynchronously for the realm passed as argument. */ -RLM_API realm_async_transaction_token_t* -realm_async_begin_transaction(realm_t* realm, realm_on_realm_async_begin_transaction_func_t, - realm_userdata_t userdata, realm_free_userdata_func_t userdata_free, bool* notify_only); +RLM_API unsigned int +realm_async_begin_write(realm_t* realm, realm_async_begin_write_func_t, + realm_userdata_t userdata, realm_free_userdata_func_t userdata_free, bool notify_only); /** * commit a transaction asynchronously for the realm passed as argument. */ -RLM_API realm_async_transaction_token_t* -realm_async_commit_transaction(realm_t* realm, realm_on_realm_async_commit_transaction_funct_t, +RLM_API unsigned int +realm_async_commit(realm_t* realm, realm_async_commit_func_t, realm_userdata_t userdata, realm_free_userdata_func_t userdata_free, - bool* allow_grouping); + bool allow_grouping); /** * Cancel the transaction referenced by the token passed as argument and set the optional boolean flag in order to * inform the caller if the transaction was cancelled. */ -RLM_API bool realm_async_cancel_transaction(realm_t* realm, realm_async_transaction_token_t* token, bool* cancelled); +RLM_API bool realm_async_cancel(realm_t* realm, unsigned int token, bool* cancelled); /** * Add a callback that will be invoked every time the view of this file is updated. diff --git a/src/realm/object-store/c_api/realm.cpp b/src/realm/object-store/c_api/realm.cpp index 559c2d1c4b8..440a9b8b40e 100644 --- a/src/realm/object-store/c_api/realm.cpp +++ b/src/realm/object-store/c_api/realm.cpp @@ -167,26 +167,21 @@ RLM_API bool realm_rollback(realm_t* realm) }); } -RLM_API realm_async_transaction_token_t* -realm_async_begin_transaction(realm_t* realm, realm_on_realm_async_begin_transaction_func_t callback, - realm_userdata_t userdata, realm_free_userdata_func_t userdata_free, bool* notify_only) +RLM_API unsigned int realm_async_begin_write(realm_t* realm, realm_async_begin_write_func_t callback, + realm_userdata_t userdata, realm_free_userdata_func_t userdata_free, + bool notify_only) { - const auto notify_only_value = notify_only ? *notify_only : false; auto cb = [realm, callback, userdata = UserdataPtr{userdata, userdata_free}]() { callback(realm, userdata.get()); }; return wrap_err([&]() { - auto handle = (*realm)->async_begin_transaction(std::move(cb), notify_only_value); - return new realm_async_transaction_token_t{handle}; + return (*realm)->async_begin_transaction(std::move(cb), notify_only); }); } -RLM_API realm_async_transaction_token_t* -realm_async_commit_transaction(realm_t* realm, realm_on_realm_async_commit_transaction_funct_t callback, - realm_userdata_t userdata, realm_free_userdata_func_t userdata_free, - bool* allow_grouping) +RLM_API unsigned int realm_async_commit(realm_t* realm, realm_async_commit_func_t callback, realm_userdata_t userdata, + realm_free_userdata_func_t userdata_free, bool allow_grouping) { - const auto allowing_grouping_value = allow_grouping ? *allow_grouping : false; auto cb = [realm, callback, userdata = UserdataPtr{userdata, userdata_free}](std::exception_ptr err) { if (err) { try { @@ -201,15 +196,14 @@ realm_async_commit_transaction(realm_t* realm, realm_on_realm_async_commit_trans } }; return wrap_err([&]() { - auto handle = (*realm)->async_commit_transaction(std::move(cb), allowing_grouping_value); - return new realm_async_transaction_token_t{handle}; + return (*realm)->async_commit_transaction(std::move(cb), allow_grouping); }); } -RLM_API bool realm_async_cancel_transaction(realm_t* realm, realm_async_transaction_token_t* token, bool* cancelled) +RLM_API bool realm_async_cancel(realm_t* realm, unsigned int token, bool* cancelled) { return wrap_err([&]() { - auto res = (*realm)->async_cancel_transaction(token->token()); + auto res = (*realm)->async_cancel_transaction(token); if (cancelled) *cancelled = res; return true; diff --git a/src/realm/object-store/c_api/types.hpp b/src/realm/object-store/c_api/types.hpp index a95ad4c2fca..2cefc41b0db 100644 --- a/src/realm/object-store/c_api/types.hpp +++ b/src/realm/object-store/c_api/types.hpp @@ -501,21 +501,6 @@ struct realm_refresh_callback_token : realm_callback_token { ~realm_refresh_callback_token() override; }; -struct realm_async_transaction_token : realm::c_api::WrapC { - realm_async_transaction_token(unsigned token) - : m_token(token) - { - } - ~realm_async_transaction_token() override = default; - unsigned token() const - { - return m_token; - } - -private: - unsigned m_token; -}; - struct realm_query : realm::c_api::WrapC { realm::Query query; std::weak_ptr weak_realm; diff --git a/test/object-store/c_api/c_api.cpp b/test/object-store/c_api/c_api.cpp index acc541e14b7..9f9c52f51f3 100644 --- a/test/object-store/c_api/c_api.cpp +++ b/test/object-store/c_api/c_api.cpp @@ -1099,7 +1099,8 @@ TEST_CASE("C API", "[c_api]") { }); REQUIRE(TestingObj::get().done); }; - auto token_begin = cptr(realm_async_begin_transaction( + + realm_async_begin_write( realm, [](realm_t* realm, void*) { auto token_refresh = cptr(realm_add_realm_refresh_callback( @@ -1109,14 +1110,14 @@ TEST_CASE("C API", "[c_api]") { }, &(TestingObj::get().realm_refresh_callback_called), [](void*) {})); - auto token_commit = cptr(realm_async_commit_transaction( + realm_async_commit( realm, [](realm_t*, void*, bool, const char*) { TestingObj::get().done = true; }, - nullptr, nullptr, nullptr)); + nullptr, nullptr, false); }, - nullptr, nullptr, nullptr)); + nullptr, nullptr, false); wait_for_done(); CHECK(TestingObj::get().realm_refresh_callback_called); From c2937046e8b6b0cfec5da01049d846547342dd17 Mon Sep 17 00:00:00 2001 From: Nicola Cabiddu Date: Fri, 26 Aug 2022 17:55:44 +0100 Subject: [PATCH 5/6] appease format checks --- src/realm.h | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/realm.h b/src/realm.h index 5f439d6d1ef..f7be0177507 100644 --- a/src/realm.h +++ b/src/realm.h @@ -373,8 +373,7 @@ typedef void (*realm_on_collection_change_func_t)(realm_userdata_t userdata, con typedef void (*realm_on_realm_change_func_t)(realm_userdata_t userdata); typedef void (*realm_on_realm_refresh_func_t)(realm_userdata_t userdata); typedef void (*realm_async_begin_write_func_t)(realm_t*, realm_userdata_t userdata); -typedef void (*realm_async_commit_func_t)(realm_t*, realm_userdata_t userdata, bool error, - const char* desc); +typedef void (*realm_async_commit_func_t)(realm_t*, realm_userdata_t userdata, bool error, const char* desc); /** * Callback for realm schema changed notifications. @@ -1066,17 +1065,15 @@ RLM_API bool realm_rollback(realm_t*); /** * start a new write transaction asynchronously for the realm passed as argument. */ -RLM_API unsigned int -realm_async_begin_write(realm_t* realm, realm_async_begin_write_func_t, - realm_userdata_t userdata, realm_free_userdata_func_t userdata_free, bool notify_only); +RLM_API unsigned int realm_async_begin_write(realm_t* realm, realm_async_begin_write_func_t, + realm_userdata_t userdata, realm_free_userdata_func_t userdata_free, + bool notify_only); /** * commit a transaction asynchronously for the realm passed as argument. */ -RLM_API unsigned int -realm_async_commit(realm_t* realm, realm_async_commit_func_t, - realm_userdata_t userdata, realm_free_userdata_func_t userdata_free, - bool allow_grouping); +RLM_API unsigned int realm_async_commit(realm_t* realm, realm_async_commit_func_t, realm_userdata_t userdata, + realm_free_userdata_func_t userdata_free, bool allow_grouping); /** * Cancel the transaction referenced by the token passed as argument and set the optional boolean flag in order to From b95fc854222702aad1174907f89cb967d412b432 Mon Sep 17 00:00:00 2001 From: Nicola Cabiddu Date: Mon, 29 Aug 2022 10:09:45 +0100 Subject: [PATCH 6/6] remove redundant realm param from callback --- src/realm.h | 4 ++-- src/realm/object-store/c_api/realm.cpp | 10 +++++----- test/object-store/c_api/c_api.cpp | 7 +++++-- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/realm.h b/src/realm.h index f7be0177507..81622712e95 100644 --- a/src/realm.h +++ b/src/realm.h @@ -372,8 +372,8 @@ typedef void (*realm_on_object_change_func_t)(realm_userdata_t userdata, const r typedef void (*realm_on_collection_change_func_t)(realm_userdata_t userdata, const realm_collection_changes_t*); typedef void (*realm_on_realm_change_func_t)(realm_userdata_t userdata); typedef void (*realm_on_realm_refresh_func_t)(realm_userdata_t userdata); -typedef void (*realm_async_begin_write_func_t)(realm_t*, realm_userdata_t userdata); -typedef void (*realm_async_commit_func_t)(realm_t*, realm_userdata_t userdata, bool error, const char* desc); +typedef void (*realm_async_begin_write_func_t)(realm_userdata_t userdata); +typedef void (*realm_async_commit_func_t)(realm_userdata_t userdata, bool error, const char* desc); /** * Callback for realm schema changed notifications. diff --git a/src/realm/object-store/c_api/realm.cpp b/src/realm/object-store/c_api/realm.cpp index 440a9b8b40e..5f5689ab309 100644 --- a/src/realm/object-store/c_api/realm.cpp +++ b/src/realm/object-store/c_api/realm.cpp @@ -171,8 +171,8 @@ RLM_API unsigned int realm_async_begin_write(realm_t* realm, realm_async_begin_w realm_userdata_t userdata, realm_free_userdata_func_t userdata_free, bool notify_only) { - auto cb = [realm, callback, userdata = UserdataPtr{userdata, userdata_free}]() { - callback(realm, userdata.get()); + auto cb = [callback, userdata = UserdataPtr{userdata, userdata_free}]() { + callback(userdata.get()); }; return wrap_err([&]() { return (*realm)->async_begin_transaction(std::move(cb), notify_only); @@ -182,17 +182,17 @@ RLM_API unsigned int realm_async_begin_write(realm_t* realm, realm_async_begin_w RLM_API unsigned int realm_async_commit(realm_t* realm, realm_async_commit_func_t callback, realm_userdata_t userdata, realm_free_userdata_func_t userdata_free, bool allow_grouping) { - auto cb = [realm, callback, userdata = UserdataPtr{userdata, userdata_free}](std::exception_ptr err) { + auto cb = [callback, userdata = UserdataPtr{userdata, userdata_free}](std::exception_ptr err) { if (err) { try { std::rethrow_exception(err); } catch (const std::exception& e) { - callback(nullptr, userdata.get(), true, e.what()); + callback(userdata.get(), true, e.what()); } } else { - callback(realm, userdata.get(), false, nullptr); + callback(userdata.get(), false, nullptr); } }; return wrap_err([&]() { diff --git a/test/object-store/c_api/c_api.cpp b/test/object-store/c_api/c_api.cpp index 9f9c52f51f3..8d4473a5c52 100644 --- a/test/object-store/c_api/c_api.cpp +++ b/test/object-store/c_api/c_api.cpp @@ -1091,6 +1091,7 @@ TEST_CASE("C API", "[c_api]") { } bool done{false}; bool realm_refresh_callback_called{false}; + realm_t* realm{nullptr}; }; auto wait_for_done = [&]() { @@ -1099,10 +1100,12 @@ TEST_CASE("C API", "[c_api]") { }); REQUIRE(TestingObj::get().done); }; + TestingObj::get().realm = realm; realm_async_begin_write( realm, - [](realm_t* realm, void*) { + [](void*) { + auto realm = TestingObj::get().realm; auto token_refresh = cptr(realm_add_realm_refresh_callback( realm, [](void* userdata) { @@ -1112,7 +1115,7 @@ TEST_CASE("C API", "[c_api]") { realm_async_commit( realm, - [](realm_t*, void*, bool, const char*) { + [](void*, bool, const char*) { TestingObj::get().done = true; }, nullptr, nullptr, false);