diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ac28006b..aff9d0a54 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,10 @@ * Receiving a `write_not_allowed` error from the server would have led to a crash. (Core 13.22.0) * Fix interprocess locking for concurrent realm file access resulting in a interprocess deadlock on FAT32/exFAT filesystems. (Core 13.23.0) * Fixed RealmObject not overriding `hashCode`, which would lead to sets of RealmObjects potentially containing duplicates. ([#1418](https://github.com/realm/realm-dart/issues/1418)) +* `realm.subscriptions.waitForSynchronization` will now correctly receive an error if a fatal session error occurs that would prevent it from ever completing. Previously the future would never resolve. (Core 13.23.3) +* Fixed FLX subscriptions not being sent to the server if the session was interrupted during bootstrapping. (Core 13.23.3) +* Fixed application crash with 'KeyNotFound' exception when subscriptions are marked complete after a client reset. (Core 13.23.3) +* A crash at a very specific time during a DiscardLocal client reset on a FLX Realm could leave subscriptions in an invalid state. (Core 13.23.4) ### Compatibility * Realm Studio: 13.0.0 or later. diff --git a/lib/src/native/realm_bindings.dart b/lib/src/native/realm_bindings.dart index 8a5ef8b25..7de5bcec7 100644 --- a/lib/src/native/realm_bindings.dart +++ b/lib/src/native/realm_bindings.dart @@ -8044,7 +8044,7 @@ class RealmLibrary { /// be called each time the notify callback passed to the scheduler /// is invoked. void realm_scheduler_perform_work( - ffi.Pointer arg0, + ffi.Pointer arg0, ) { return _realm_scheduler_perform_work( arg0, @@ -8053,10 +8053,10 @@ class RealmLibrary { late final _realm_scheduler_perform_workPtr = _lookup< ffi - .NativeFunction)>>( + .NativeFunction)>>( 'realm_scheduler_perform_work'); late final _realm_scheduler_perform_work = _realm_scheduler_perform_workPtr - .asFunction)>(); + .asFunction)>(); /// For platforms with no default scheduler implementation, register a factory /// function which can produce custom schedulers. If there is a platform-specific @@ -11943,7 +11943,9 @@ typedef realm_scheduler_is_same_as_func_t = ffi.Pointer< ffi.Bool Function(ffi.Pointer scheduler_userdata_1, ffi.Pointer scheduler_userdata_2)>>; typedef realm_scheduler_notify_func_t = ffi.Pointer< - ffi.NativeFunction userdata)>>; + ffi.NativeFunction< + ffi.Void Function(ffi.Pointer userdata, + ffi.Pointer work_queue)>>; typedef realm_scheduler_t = realm_scheduler; final class realm_schema extends ffi.Opaque {} @@ -12373,4 +12375,8 @@ final class realm_websocket_observer extends ffi.Opaque {} typedef realm_websocket_observer_t = realm_websocket_observer; +final class realm_work_queue extends ffi.Opaque {} + +typedef realm_work_queue_t = realm_work_queue; + final class shared_realm extends ffi.Opaque {} diff --git a/lib/src/native/realm_core.dart b/lib/src/native/realm_core.dart index 5f02efb8c..4d6a34675 100644 --- a/lib/src/native/realm_core.dart +++ b/lib/src/native/realm_core.dart @@ -651,8 +651,9 @@ class _RealmCore { return SchedulerHandle._(schedulerPtr); } - void invokeScheduler(SchedulerHandle schedulerHandle) { - _realmLib.realm_scheduler_perform_work(schedulerHandle._pointer); + void invokeScheduler(int workQueue) { + final queuePointer = Pointer.fromAddress(workQueue); + _realmLib.realm_scheduler_perform_work(queuePointer); } RealmHandle openRealm(Configuration config) { diff --git a/lib/src/scheduler.dart b/lib/src/scheduler.dart index f5e98ee1e..6918598c9 100644 --- a/lib/src/scheduler.dart +++ b/lib/src/scheduler.dart @@ -38,8 +38,10 @@ class Scheduler { final level = message[0] as int; final text = message[1] as String; Realm.logger.log(LevelExt.fromInt(level), text); + } else if (message is int) { + realmCore.invokeScheduler(message); } else { - realmCore.invokeScheduler(handle); + Realm.logger.log(RealmLogLevel.error, 'Unexpected Scheduler message type: ${message.runtimeType} - $message'); } }; diff --git a/src/realm-core b/src/realm-core index 56a048d9f..a2e743a38 160000 --- a/src/realm-core +++ b/src/realm-core @@ -1 +1 @@ -Subproject commit 56a048d9f450445f2d52c7405f3019a533bdaa3f +Subproject commit a2e743a388a3d70230ade165e0edc1d2f025bc95 diff --git a/src/realm_dart_scheduler.cpp b/src/realm_dart_scheduler.cpp index 537105dec..5c75e2e9a 100644 --- a/src/realm_dart_scheduler.cpp +++ b/src/realm_dart_scheduler.cpp @@ -33,7 +33,8 @@ struct SchedulerData { void* callback_userData = nullptr; realm_free_userdata_func_t free_userData_func = nullptr; - SchedulerData(uint64_t isolate, Dart_Port dartPort) : port(dartPort), threadId(std::this_thread::get_id()), isolateId(isolate) + SchedulerData(uint64_t isolate, Dart_Port dartPort) + : port(dartPort), threadId(std::this_thread::get_id()), isolateId(isolate) {} }; @@ -46,9 +47,9 @@ void realm_dart_scheduler_free_userData(void* userData) { } //This can be invoked on any thread. -void realm_dart_scheduler_notify(void* userData) { +void realm_dart_scheduler_notify(void* userData, realm_work_queue_t* work_queue) { auto& schedulerData = *static_cast(userData); - std::uintptr_t pointer = reinterpret_cast(userData); + std::uintptr_t pointer = reinterpret_cast(work_queue); Dart_PostInteger_DL(schedulerData.port, pointer); } @@ -84,14 +85,12 @@ bool realm_dart_scheduler_can_deliver_notifications(void* userData) { RLM_API realm_scheduler_t* realm_dart_create_scheduler(uint64_t isolateId, Dart_Port port) { SchedulerData* schedulerData = new SchedulerData(isolateId, port); - realm_scheduler_t* realm_scheduler = realm_scheduler_new(schedulerData, + return realm_scheduler_new(schedulerData, realm_dart_scheduler_free_userData, realm_dart_scheduler_notify, realm_dart_scheduler_is_on_thread, realm_dart_scheduler_is_same_as, realm_dart_scheduler_can_deliver_notifications); - - return realm_scheduler; } //Used for debugging