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

implement NativeFinalizers in Realm #1044

Merged
merged 4 commits into from
Nov 25, 2022
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
2 changes: 0 additions & 2 deletions ffigen/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ compiler-opts:
- '-DFFI_GEN'
- '-I../src/realm-core/src'
- '-I../src/dart-dl'
typedef-map:
'size_t' : 'IntPtr'
sort: true
functions:
exclude:
Expand Down
36 changes: 36 additions & 0 deletions lib/src/native/realm_bindings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1846,6 +1846,25 @@ class RealmLibrary {
.asFunction<
void Function(ffi.Pointer<realm_async_open_task_t>, int)>();

ffi.Pointer<ffi.Void> realm_attach_finalizer(
Object handle,
ffi.Pointer<ffi.Void> realmPtr,
int size,
) {
return _realm_attach_finalizer(
handle,
realmPtr,
size,
);
}

late final _realm_attach_finalizerPtr = _lookup<
ffi.NativeFunction<
ffi.Pointer<ffi.Void> Function(ffi.Handle, ffi.Pointer<ffi.Void>,
ffi.Int)>>('realm_attach_finalizer');
late final _realm_attach_finalizer = _realm_attach_finalizerPtr.asFunction<
ffi.Pointer<ffi.Void> Function(Object, ffi.Pointer<ffi.Void>, int)>();

int realm_auth_credentials_get_provider(
ffi.Pointer<realm_app_credentials_t> arg0,
) {
Expand Down Expand Up @@ -3462,6 +3481,23 @@ class RealmLibrary {
late final _realm_delete_files = _realm_delete_filesPtr.asFunction<
bool Function(ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Bool>)>();

void realm_dettach_finalizer(
ffi.Pointer<ffi.Void> finalizableHandle,
Object handle,
) {
return _realm_dettach_finalizer(
finalizableHandle,
handle,
);
}

late final _realm_dettach_finalizerPtr = _lookup<
ffi.NativeFunction<
ffi.Void Function(
ffi.Pointer<ffi.Void>, ffi.Handle)>>('realm_dettach_finalizer');
late final _realm_dettach_finalizer = _realm_dettach_finalizerPtr
.asFunction<void Function(ffi.Pointer<ffi.Void>, Object)>();

/// Subscribe to notifications for this object.
///
/// @return A non-null pointer if no exception occurred.
Expand Down
14 changes: 10 additions & 4 deletions lib/src/native/realm_core.dart
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ class _RealmCore {
static const libraryVersion = '0.8.0+rc';
late String nativeLibraryVersion = _realmLib.realm_dart_library_version().cast<Utf8>().toDartString();

// for debugging only. Enable in realm_dart.cpp
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we leave this commented out here for the future?

// void invokeGC() {
// _realmLib.realm_dart_gc();
// }

LastError? getLastError(Allocator allocator) {
final error = allocator<realm_error_t>();
final success = _realmLib.realm_get_last_error(error);
Expand Down Expand Up @@ -2312,9 +2317,8 @@ void _tearDownFinalizationTrace(Object value, Object finalizationToken) {
_traceFinalization(finalizationToken);
}

final _nativeFinalizer = NativeFinalizer(_realmLib.addresses.realm_release);

abstract class HandleBase<T extends NativeType> implements Finalizable {
late Pointer<Void> _finalizableHandle;
Pointer<T> _pointer;
bool get released => _pointer == nullptr;
final bool isUnowned;
Expand All @@ -2323,7 +2327,8 @@ abstract class HandleBase<T extends NativeType> implements Finalizable {
void keepAlive() {}

HandleBase(this._pointer, int size) : isUnowned = false {
_nativeFinalizer.attach(this, _pointer.cast(), detach: this, externalSize: size);
_finalizableHandle = _realmLib.realm_attach_finalizer(this, _pointer.cast(), size);

if (_enableFinalizerTrace) {
_setupFinalizationTrace(this, _pointer);
}
Expand All @@ -2347,7 +2352,8 @@ abstract class HandleBase<T extends NativeType> implements Finalizable {
_releaseCore();

if (!isUnowned) {
_nativeFinalizer.detach(this);
_realmLib.realm_dettach_finalizer(_finalizableHandle, this);

_realmLib.realm_release(_pointer.cast());
}

Expand Down
3 changes: 3 additions & 0 deletions lib/src/realm_class.dart
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,9 @@ class Realm implements Finalizable {
/// This is a workaround of a Dart VM bug and will be removed in a future version of the SDK.
static void shutdown() => scheduler.stop();

// For debugging only. Enable in realm_dart.cpp
// static void gc() => realmCore.invokeGC();

void _ensureManagedByThis(RealmEntity entity, String operation) {
if (entity.realm != this) {
if (entity.isFrozen) {
Expand Down
22 changes: 21 additions & 1 deletion src/realm_dart.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,5 +93,25 @@ RLM_API void realm_dart_invoke_unlock_callback(bool success, void* unlockFunc)
(*castFunc)(success);
}

// stamped into the library by the build system (see prepare-release.yml)
// Stamped into the library by the build system (see prepare-release.yml)
// Keep this method as it is written and do not format it.
// We have a github workflow that looks for and replaces this string as it is written here.
RLM_API const char* realm_dart_library_version() { return "0.8.0+rc"; }

//for debugging only
// RLM_API void realm_dart_gc() {
// Dart_ExecuteInternalCommand_DL("gc-now", nullptr);
// }

void handle_finalizer(void* isolate_callback_data, void* realmPtr) {
realm_release(realmPtr);
}

RLM_API void* realm_attach_finalizer(Dart_Handle handle, void* realmPtr, int size) {
return Dart_NewFinalizableHandle_DL(handle, realmPtr, size, handle_finalizer);
}

RLM_API void realm_dettach_finalizer(void* finalizableHandle, Dart_Handle handle) {
Dart_FinalizableHandle finalHandle = reinterpret_cast<Dart_FinalizableHandle>(finalizableHandle);
return Dart_DeleteFinalizableHandle_DL(finalHandle, handle);
}
7 changes: 7 additions & 0 deletions src/realm_dart.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,11 @@ RLM_API void realm_dart_invoke_unlock_callback(bool success, void* unlockFunc);

RLM_API const char* realm_dart_library_version();

// for debugging only. Enable in realm_dart.cpp
// RLM_API void realm_dart_gc();

RLM_API void* realm_attach_finalizer(Dart_Handle handle, void* realmPtr, int size);
RLM_API void realm_dettach_finalizer(void* finalizableHandle, Dart_Handle handle);


#endif // REALM_DART_H