-
Notifications
You must be signed in to change notification settings - Fork 1.7k
[ffi] Creating an external string with a Dart function from within Dart causes a crash. #50452
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
Comments
This still applies. Native Finalizers are run eagerly on garbage collection and run on isolate shutdown. They cannot run Dart code because they run eagerly during GCs in synchronous code. Finalizers do not run on isolate shutdown (we're assuming you're cleaning up Dart things in finalizers and if an isolate shuts down, all the Dart objects are gone). Moreover, Finalizers that run Dart code are postponed till the next yield point (e.g. If you want to free your native string, you should define your finalization function in C/C++ and use a native finalizer. |
Thank you, that makes sense to me. I'd like to manage the storage that underlies the external string from within Dart code (multiple isolates will need to create external strings over the same native memory, so I plan to implement some GC scheme myself) and this motivates the following question: To report to my Dart code whether an external string has been finalized, I'd have to leave some information behind from within native code, and periodically poll that information from within Dart code, correct? or do you perhaps see a better option that involves less native code? |
That sounds like you need a ref-count in C++ and a
The |
I've tried to clarify my plan with the following diagram.
|
Thanks for the diagram @modulovalue! This clarifies your goal.
I believe it might be the wrong design goal to try to manage native memory with Dart code instead of in native code. Assuming that all memory is one contiguous region that cannot be freed with sub-regions, it doesn't matter that a specific isolate only depends on sub-region. So still a normal ref-count on the whole region would be simpler than trying to keep track of sub-regions. Is this assumption correct @modulovalue? I strongly suggest doing the refcounting and freeing in native code. (If you really want to do refcounting in Dart: The |
Thank you for the help so far dcharkes!
I believe your assumption is not correct for my particular use case. The reason why I'm saying that is that I have a Piece table where sub-regions may depend on other sub-regions from within a single isolate. (Perhaps my descriptions so far were too oversimplified (as I don't expect people to be familiar with piece tables), but I plan to share the whole piece table between isolates to have fast access to a version tree of changes. I'll unfortunately need to store ref counters over regions, but I have the necessary infrastructure for that already in place in the form of interval trees, all that I'm missing now is the ability for zero-cost strings across isolates backed by native memory and reliable ref counting). |
Thank you, I haven't considered that yet, I'll try that. |
It worked, thank you @dcharkes! Your suggestion has lead me down the right path: Since this issue does not report any unexpected behavior, but a possible inconvenience, and because dcharkes has provided a workaround, I'm going to close it now. |
I'm trying to create an external string so I can manage the storage of a String outside of Darts heap.
Consider the following example which allocates some memory and calls into
Dart_NewExternalUTF16String
:I get a string as expected i.e. the print expression outputs 'DDDDD', but the program crashes afterwards with:
I remember reading somewhere that native finalizers can't call into Dart code. Is that what causes this error?
Does this restriction still apply? (I presume this doesn't have to be case since there are Finalizers now in Dart that support dart functions.)
Or am I using this API incorrectly?
The text was updated successfully, but these errors were encountered: