Watch
1
0
Fork
You've already forked nexus
0
forked from Nexus/nexus

tweak memory management

This commit is contained in:
Henry Hiles 2026-11-05 20:51:28 -05:00
commit ea29889e5c
Signed by: Henry-Hiles
SSH key fingerprint: SHA256:VKQUdS31Q90KvX7EkKMHMBpUspcmItAh86a+v7PGiIs
2 changed files with 26 additions and 32 deletions

View file

@ -79,34 +79,26 @@ class ClientController(final String? accountId) extends AsyncNotifier<int> {
final environment = await _environment(account); final environment = await _environment(account);
debugPrint("Setting Gomuks env for $account..."); debugPrint("Setting Gomuks env for $account...");
for (final MapEntry(:key, :value) in environment.entries) { using((arena) {
final keyPtr = key.toNativeUtf8().cast<Char>(); for (final MapEntry(:key, :value) in environment.entries) {
final valuePtr = value.toNativeUtf8().cast<Char>(); GomuksSetEnv(
try { key.toNativeUtf8(allocator: arena).cast(),
GomuksSetEnv(keyPtr, valuePtr); value.toNativeUtf8(allocator: arena).cast(),
} finally { );
calloc
..free(keyPtr)
..free(valuePtr);
} }
} }, malloc);
debugPrint("Initializing Gomuks..."); debugPrint("Initializing Gomuks...");
final bufferPointer = GomuksConfig( final config = GomuksConfig(
matrix: .new( matrix: .new(
initialDeviceDisplayName: initialDeviceDisplayName:
"Nexus on ${toBeginningOfSentenceCase(Platform.operatingSystem)}", "Nexus on ${toBeginningOfSentenceCase(Platform.operatingSystem)}",
), ),
).toJson().toGomuksBufferPtr(); ).toJson();
final handle = using(
final int handle; (arena) => GomuksInit(config.toGomuksBufferPtr(arena).ref),
try { malloc,
handle = GomuksInit(bufferPointer.ref); );
} finally {
calloc
..free(bufferPointer.ref.base)
..free(bufferPointer);
}
if (!ref.mounted) { if (!ref.mounted) {
GomuksDestroy(handle); GomuksDestroy(handle);
@ -233,13 +225,16 @@ class ClientController(final String? accountId) extends AsyncNotifier<int> {
String command, [ String command, [
Map<String, dynamic> data = const {}, Map<String, dynamic> data = const {},
]) => callGomuksMethod(data, (handle, data, callback) { ]) => callGomuksMethod(data, (handle, data, callback) {
final commandPointer = command.toNativeUtf8().cast<Char>(); // gomuks copies the command name before returning
try { using(
GomuksSubmitCommandAsync(handle, commandPointer, data, callback); (arena) => GomuksSubmitCommandAsync(
} finally { handle,
// gomuks copies the command name before returning command.toNativeUtf8(allocator: arena).cast(),
calloc.free(commandPointer); data,
} callback,
),
malloc,
);
}); });
Future<void> redactEvent(RedactEventRequest report) => Future<void> redactEvent(RedactEventRequest report) =>

View file

@ -2,7 +2,6 @@ import "dart:convert";
import "dart:ffi"; import "dart:ffi";
import "dart:typed_data"; import "dart:typed_data";
import "package:ffi/ffi.dart";
import "package:nexus/src/third_party/gomuks.g.dart"; import "package:nexus/src/third_party/gomuks.g.dart";
extension GomuksOwnedBufferToX on GomuksOwnedBuffer { extension GomuksOwnedBufferToX on GomuksOwnedBuffer {
@ -29,13 +28,13 @@ extension JsonToGomuksBuffer on Map<String, dynamic> {
return buffer; return buffer;
} }
Pointer<GomuksBorrowedBuffer> toGomuksBufferPtr() { Pointer<GomuksBorrowedBuffer> toGomuksBufferPtr(Allocator allocator) {
final bytes = utf8.encode(json.encode(this)); final bytes = utf8.encode(json.encode(this));
final dataPtr = calloc<Uint8>(bytes.length); final dataPtr = allocator<Uint8>(bytes.length);
dataPtr.asTypedList(bytes.length).setAll(0, bytes); dataPtr.asTypedList(bytes.length).setAll(0, bytes);
return calloc<GomuksBorrowedBuffer>() return allocator<GomuksBorrowedBuffer>()
..ref.base = dataPtr ..ref.base = dataPtr
..ref.length = bytes.length; ..ref.length = bytes.length;
} }