Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Always use persistent handles when passing dart objects as userdata to callbacks #1491

Merged
merged 3 commits into from
Jan 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
## vNext (TBD)

### Enhancements
* None
* Added `RealmObject.getBacklinks<SourceType>('sourceProperty')` which is a method allowing you to look up all objects of type `SourceType` which link to the current object via their `sourceProperty` property. (Issue [#1480](https://github.com/realm/realm-dart/issues/1480))

### Fixed
* None
* Fix a possible hang (or in rare cases crash) during notification handling. (Issue [#1492](https://github.com/realm/realm-dart/issues/1492))
* Fix Flutter app build on Linux. A contribution from [thiagokisaki](https://github.com/thiagokisaki). (PR [#1488](https://github.com/realm/realm-dart/pull/1488))

### Compatibility
* Realm Studio: 13.0.0 or later.

### Internal
* Using Core x.y.z.
* Using Core 13.26.0

## 1.7.0 (2024-01-23)

Expand Down Expand Up @@ -40,7 +41,6 @@
The map keys may not contain `.` or start with `$`. (Issue [#685](https://github.com/realm/realm-dart/issues/685))
* Added a new exception - `MigrationRequiredException` that will be thrown when a local Realm is opened with a schema that differs from the schema on disk and no migration callback is supplied. Additionally, a `helpLink` property has been added to `RealmException` and its subclasses to provide a link to the documentation for the error. (Issue [#1448](https://github.com/realm/realm-dart/issues/1448))
* Downgrade minimum dependencies to Dart 3.0.0 and Flutter 3.10.0. (PR [#1457](https://github.com/realm/realm-dart/pull/1457))
* Added `RealmObject.getBacklinks<SourceType>('sourceProperty')` which is a method allowing you to look up all objects of type `SourceType` which link to the current object via their `sourceProperty` property. (Issue [#1480](https://github.com/realm/realm-dart/issues/1480))

### Fixed
* Fixed warnings being emitted by the realm generator requesting that `xyz.g.dart` be included with `part 'xyz.g.dart';` for `xyz.dart` files that import `realm` but don't have realm models defined. Those should not need generated parts and including the part file would have resulted in an empty file with `// ignore_for_file: type=lint` being generated. (PR [#1443](https://github.com/realm/realm-dart/pull/1443))
Expand Down
36 changes: 0 additions & 36 deletions lib/src/native/realm_bindings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3770,21 +3770,6 @@ class RealmLibrary {
_realm_dart_object_to_persistent_handlePtr
.asFunction<ffi.Pointer<ffi.Void> Function(Object)>();

ffi.Pointer<ffi.Void> realm_dart_object_to_weak_handle(
Object handle,
) {
return _realm_dart_object_to_weak_handle(
handle,
);
}

late final _realm_dart_object_to_weak_handlePtr =
_lookup<ffi.NativeFunction<ffi.Pointer<ffi.Void> Function(ffi.Handle)>>(
'realm_dart_object_to_weak_handle');
late final _realm_dart_object_to_weak_handle =
_realm_dart_object_to_weak_handlePtr
.asFunction<ffi.Pointer<ffi.Void> Function(Object)>();

Object realm_dart_persistent_handle_to_object(
ffi.Pointer<ffi.Void> handle,
) {
Expand Down Expand Up @@ -4113,21 +4098,6 @@ class RealmLibrary {
void Function(
ffi.Pointer<ffi.Void>, ffi.Pointer<realm_app_error_t>)>();

Object realm_dart_weak_handle_to_object(
ffi.Pointer<ffi.Void> handle,
) {
return _realm_dart_weak_handle_to_object(
handle,
);
}

late final _realm_dart_weak_handle_to_objectPtr =
_lookup<ffi.NativeFunction<ffi.Handle Function(ffi.Pointer<ffi.Void>)>>(
'realm_dart_weak_handle_to_object');
late final _realm_dart_weak_handle_to_object =
_realm_dart_weak_handle_to_objectPtr
.asFunction<Object Function(ffi.Pointer<ffi.Void>)>();

/// Deletes the following files for the given `realm_file_path` if they exist:
/// - the Realm file itself
/// - the .management folder
Expand Down Expand Up @@ -11343,9 +11313,6 @@ class _SymbolAddresses {
ffi.Pointer<ffi.NativeFunction<ffi.Pointer<ffi.Void> Function(ffi.Handle)>>
get realm_dart_object_to_persistent_handle =>
_library._realm_dart_object_to_persistent_handlePtr;
ffi.Pointer<ffi.NativeFunction<ffi.Pointer<ffi.Void> Function(ffi.Handle)>>
get realm_dart_object_to_weak_handle =>
_library._realm_dart_object_to_weak_handlePtr;
ffi.Pointer<ffi.NativeFunction<ffi.Handle Function(ffi.Pointer<ffi.Void>)>>
get realm_dart_persistent_handle_to_object =>
_library._realm_dart_persistent_handle_to_objectPtr;
Expand Down Expand Up @@ -11431,9 +11398,6 @@ class _SymbolAddresses {
ffi.Pointer<ffi.Void>, ffi.Pointer<realm_app_error_t>)>>
get realm_dart_void_completion_callback =>
_library._realm_dart_void_completion_callbackPtr;
ffi.Pointer<ffi.NativeFunction<ffi.Handle Function(ffi.Pointer<ffi.Void>)>>
get realm_dart_weak_handle_to_object =>
_library._realm_dart_weak_handle_to_objectPtr;
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
get realm_release => _library._realm_releasePtr;
}
Expand Down
63 changes: 32 additions & 31 deletions lib/src/native/realm_core.dart
Original file line number Diff line number Diff line change
Expand Up @@ -258,8 +258,8 @@ class _RealmCore {
_realmLib.realm_config_set_data_initialization_function(
configHandle._pointer,
Pointer.fromFunction(initial_data_callback, false),
config.toWeakHandle(),
nullptr,
config.toPersistentHandle(),
_realmLib.addresses.realm_dart_delete_persistent_handle,
);
}
if (config.isReadOnly) {
Expand All @@ -274,12 +274,17 @@ class _RealmCore {
_realmLib.realm_config_set_should_compact_on_launch_function(
configHandle._pointer,
Pointer.fromFunction(should_compact_callback, false),
config.toWeakHandle(),
nullptr,
config.toPersistentHandle(),
_realmLib.addresses.realm_dart_delete_persistent_handle,
);
}
if (config.migrationCallback != null) {
_realmLib.realm_config_set_migration_function(configHandle._pointer, Pointer.fromFunction(migration_callback, false), config.toWeakHandle(), nullptr);
_realmLib.realm_config_set_migration_function(
configHandle._pointer,
Pointer.fromFunction(migration_callback, false),
config.toPersistentHandle(),
_realmLib.addresses.realm_dart_delete_persistent_handle,
);
}
} else if (config is InMemoryConfiguration) {
_realmLib.realm_config_set_in_memory(configHandle._pointer, true);
Expand Down Expand Up @@ -317,8 +322,8 @@ class _RealmCore {
_realmLib.realm_config_set_should_compact_on_launch_function(
configHandle._pointer,
Pointer.fromFunction(should_compact_callback, false),
config.toWeakHandle(),
nullptr,
config.toPersistentHandle(),
_realmLib.addresses.realm_dart_delete_persistent_handle,
);
}

Expand Down Expand Up @@ -893,12 +898,12 @@ class _RealmCore {
}

static void _completeAsyncBeginWrite(Pointer<Void> userdata) {
final Completer<void> completer = userdata.toObject(isPersistent: true);
final Completer<void> completer = userdata.toObject();
completer.complete();
}

static void _completeAsyncCommit(Pointer<Void> userdata, bool error, Pointer<Char> description) {
final Completer<void> completer = userdata.toObject(isPersistent: true);
final Completer<void> completer = userdata.toObject();
if (error) {
completer.completeError(RealmException(description.cast<Utf8>().toDartString()));
} else {
Expand Down Expand Up @@ -1532,8 +1537,8 @@ class _RealmCore {
RealmNotificationTokenHandle subscribeSetNotifications(RealmSet realmSet, NotificationsController controller) {
final pointer = _realmLib.invokeGetPointer(() => _realmLib.realm_set_add_notification_callback(
realmSet.handle._pointer,
controller.toWeakHandle(),
nullptr,
controller.toPersistentHandle(),
_realmLib.addresses.realm_dart_delete_persistent_handle,
nullptr,
Pointer.fromFunction(collection_change_callback),
));
Expand Down Expand Up @@ -1733,8 +1738,8 @@ class _RealmCore {
RealmNotificationTokenHandle subscribeResultsNotifications(RealmResults results, NotificationsController controller) {
final pointer = _realmLib.invokeGetPointer(() => _realmLib.realm_results_add_notification_callback(
results.handle._pointer,
controller.toWeakHandle(),
nullptr,
controller.toPersistentHandle(),
_realmLib.addresses.realm_dart_delete_persistent_handle,
nullptr,
Pointer.fromFunction(collection_change_callback),
));
Expand All @@ -1745,8 +1750,8 @@ class _RealmCore {
RealmNotificationTokenHandle subscribeListNotifications(RealmList list, NotificationsController controller) {
final pointer = _realmLib.invokeGetPointer(() => _realmLib.realm_list_add_notification_callback(
list.handle._pointer,
controller.toWeakHandle(),
nullptr,
controller.toPersistentHandle(),
_realmLib.addresses.realm_dart_delete_persistent_handle,
nullptr,
Pointer.fromFunction(collection_change_callback),
));
Expand All @@ -1757,8 +1762,8 @@ class _RealmCore {
RealmNotificationTokenHandle subscribeObjectNotifications(RealmObjectBase object, NotificationsController controller) {
final pointer = _realmLib.invokeGetPointer(() => _realmLib.realm_object_add_notification_callback(
object.handle._pointer,
controller.toWeakHandle(),
nullptr,
controller.toPersistentHandle(),
_realmLib.addresses.realm_dart_delete_persistent_handle,
nullptr,
Pointer.fromFunction(object_change_callback),
));
Expand All @@ -1769,8 +1774,8 @@ class _RealmCore {
RealmNotificationTokenHandle subscribeMapNotifications(RealmMap map, NotificationsController controller) {
final pointer = _realmLib.invokeGetPointer(() => _realmLib.realm_dictionary_add_notification_callback(
map.handle._pointer,
controller.toWeakHandle(),
nullptr,
controller.toPersistentHandle(),
_realmLib.addresses.realm_dart_delete_persistent_handle,
nullptr,
Pointer.fromFunction(map_change_callback),
));
Expand Down Expand Up @@ -2076,7 +2081,7 @@ class _RealmCore {
}

static void _app_user_completion_callback(Pointer<Void> userdata, Pointer<realm_user> user, Pointer<realm_app_error> error) {
final Completer<UserHandle> completer = userdata.toObject(isPersistent: true);
final Completer<UserHandle> completer = userdata.toObject();

if (error != nullptr) {
completer.completeWithAppError(error);
Expand Down Expand Up @@ -2127,7 +2132,7 @@ class _RealmCore {
}

static void _void_completion_callback(Pointer<Void> userdata, Pointer<realm_app_error> error) {
final Completer<void> completer = userdata.toObject(isPersistent: true);
final Completer<void> completer = userdata.toObject();

if (error != nullptr) {
completer.completeWithAppError(error);
Expand Down Expand Up @@ -2707,7 +2712,7 @@ class _RealmCore {
}

static void _app_api_key_completion_callback(Pointer<Void> userdata, Pointer<realm_app_user_apikey> apiKey, Pointer<realm_app_error> error) {
final Completer<ApiKey> completer = userdata.toObject(isPersistent: true);
final Completer<ApiKey> completer = userdata.toObject();
if (error != nullptr) {
completer.completeWithAppError(error);
return;
Expand All @@ -2716,7 +2721,7 @@ class _RealmCore {
}

static void _app_api_key_array_completion_callback(Pointer<Void> userdata, Pointer<realm_app_user_apikey> apiKey, int size, Pointer<realm_app_error> error) {
final Completer<List<ApiKey>> completer = userdata.toObject(isPersistent: true);
final Completer<List<ApiKey>> completer = userdata.toObject();

if (error != nullptr) {
completer.completeWithAppError(error);
Expand Down Expand Up @@ -2884,7 +2889,7 @@ class _RealmCore {
}

static void _call_app_function_callback(Pointer<Void> userdata, Pointer<Char> response, Pointer<realm_app_error> error) {
final Completer<String> completer = userdata.toObject(isPersistent: true);
final Completer<String> completer = userdata.toObject();

if (error != nullptr) {
completer.completeWithAppError(error);
Expand Down Expand Up @@ -3462,18 +3467,18 @@ extension on Pointer<realm_value> {
}

extension on Pointer<Void> {
T toObject<T extends Object>({bool isPersistent = false}) {
T toObject<T extends Object>() {
assert(this != nullptr, "Pointer<Void> is null");

Object object = isPersistent ? _realmLib.realm_dart_persistent_handle_to_object(this) : _realmLib.realm_dart_weak_handle_to_object(this);
Object object = _realmLib.realm_dart_persistent_handle_to_object(this);

assert(object is T, "$T expected");
return object as T;
}

Object? toUserCodeError() {
if (this != nullptr) {
final result = toObject(isPersistent: true);
final result = toObject();
_realmLib.realm_dart_delete_persistent_handle(this);
return result;
}
Expand Down Expand Up @@ -3565,10 +3570,6 @@ extension on Pointer<realm_error_t> {
}

extension on Object {
Pointer<Void> toWeakHandle() {
return _realmLib.realm_dart_object_to_weak_handle(this);
}

Pointer<Void> toPersistentHandle() {
return _realmLib.realm_dart_object_to_persistent_handle(this);
}
Expand Down
32 changes: 0 additions & 32 deletions src/realm_dart.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,38 +53,6 @@ RLM_API void realm_dart_initializeDartApiDL(void* data) {
Dart_InitializeApiDL(data);
}

class WeakHandle {
public:
WeakHandle(Dart_Handle handle) : m_weakHandle(Dart_NewWeakPersistentHandle_DL(handle, this, 1, finalize_handle)) {
}

Dart_Handle value() {
return Dart_HandleFromWeakPersistent_DL(m_weakHandle);
}

private:
~WeakHandle() {
if (m_weakHandle) {
Dart_DeleteWeakPersistentHandle_DL(m_weakHandle);
m_weakHandle = nullptr;
}
}

static void finalize_handle(void* isolate_callback_data, void* peer) {
delete reinterpret_cast<WeakHandle*>(peer);
}

Dart_WeakPersistentHandle m_weakHandle;
};

RLM_API void* realm_dart_object_to_weak_handle(Dart_Handle handle) {
return new WeakHandle(handle);
}

RLM_API Dart_Handle realm_dart_weak_handle_to_object(void* handle) {
return reinterpret_cast<WeakHandle*>(handle)->value();
}

RLM_API void* realm_dart_object_to_persistent_handle(Dart_Handle handle) {
return reinterpret_cast<void*>(Dart_NewPersistentHandle_DL(handle));
}
Expand Down
3 changes: 0 additions & 3 deletions src/realm_dart.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,6 @@

RLM_API void realm_dart_initializeDartApiDL(void* data);

RLM_API void* realm_dart_object_to_weak_handle(Dart_Handle handle);
RLM_API Dart_Handle realm_dart_weak_handle_to_object(void* handle);

RLM_API void* realm_dart_object_to_persistent_handle(Dart_Handle handle);
RLM_API Dart_Handle realm_dart_persistent_handle_to_object(void* handle);
RLM_API void realm_dart_delete_persistent_handle(void* handle);
Expand Down
Loading