Skip to content

JArray.getRange() has thread-safety problem #1151

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

Open
brandon3343 opened this issue May 16, 2024 · 4 comments
Open

JArray.getRange() has thread-safety problem #1151

brandon3343 opened this issue May 16, 2024 · 4 comments

Comments

@brandon3343
Copy link

Future<Uint8List> getIcon(String packageName) async {
    final JArray<jbyte> jArray = await getIconFromAndroid(packageName);

    // There is a thread safety issue with the following line of code, 
    return jArray.getRange(0, jArray.length).buffer.asUint8List();
}

multiple executions test(), the return value maybe incorrect.

Isolate.run(() async {
    final icon = getIcon('package1'); // maybe incorret
});
Isolate.run(() async  {
    final icon = getIcon('package2'); // maybe incorret
});
@HosseinYousefi
Copy link
Member

What is getIconFromAndroid? Also you're not awaiting the result of getIcon in Isolate.run.

Please post a minimal reproducible failing code without external dependencies.

@HosseinYousefi HosseinYousefi moved this from Todo to In Progress in JNIgen tracker May 16, 2024
@HosseinYousefi HosseinYousefi added the needs-info Additional information needed from the issue author label May 16, 2024
@brandon3343
Copy link
Author

brandon3343 commented May 17, 2024

Sorry, this is the smallest example.

the code is in app_icon.dart -> _AppIconState -> _getIcon()

class _AppIconState extends State<AppIcon> {
···
  @override
  void initState() {
    super.initState();
    _getIcon();  
    // _getIconFixed();
  }
···
}

file

jnigen_example.zip

screenshot when called _getIcon()
Screenshot_1715938195

screenshot when called _getIconFixed()
Screenshot_1715938339

@github-actions github-actions bot removed the needs-info Additional information needed from the issue author label May 18, 2024
@HosseinYousefi
Copy link
Member

This seems to be a problem with the native finalizer @dcharkes.

When I try using a custom allocator (that is not recognized by package:jni to have a nativeFree), it works:

class CustomAlloc implements Allocator {
  @override
  Pointer<T> allocate<T extends NativeType>(int byteCount, {int? alignment}) {
    return malloc.allocate(byteCount, alignment: alignment);
  }

  @override
  void free(Pointer<NativeType> pointer) {
    return malloc.free(pointer);
  }
}

And later on:

final list = iconByteArray
    .getRange(0, iconByteArray.length, allocator: CustomAlloc())
    .buffer
    .asUint8List();

In general you would want to manage the memory yourself, since keeping all of the lists inside the _cache Map would keep them forever. So your implementation of CustomAlloc could also manage the images, for instance, based on the view portion of the list view.

@HosseinYousefi
Copy link
Member

As mentioned, this is happening due to dart-lang/sdk#55800. Moving this to backlog.

@HosseinYousefi HosseinYousefi removed this from the JNI / JNIgen 0.10.0 milestone May 27, 2024
@HosseinYousefi HosseinYousefi moved this from In Progress to Backlog in JNIgen tracker May 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Backlog
Development

No branches or pull requests

2 participants