Open mraleph opened 3 years ago
After carefully reading the doc, I find that the example above seems incomplete. Please correct me if I am wrong.
- If true is returned, the message was enqueued, and finalizers for external
- typed data will eventually run, even if the receiving isolate shuts down
- before processing the message. If false is returned, the message was not
- enqueued and ownership of external typed data in the message remains with the
- caller.
Thus, maybe should add an extra free
, when return value is false
:
Dart_CObject message;
message.type = Dart_CObject_kExternalTypedData;
message.value.as_external_typed_data.type = Dart_TypedData_kUint8;
message.value.as_external_typed_data.length = length;
message.value.as_external_typed_data.data = reinterpret_cast<uint8_t*>(image);
message.value.as_external_typed_data.peer = image;
message.value.as_external_typed_data.callback = [](void* isolate_callback_data, void* peer) {
free(peer); // peer points to image buffer, see above.
};
bool result = Dart_PostCObject(port, &message);
if (!result) {
free(peer); // because the ownership remains to the caller!
}
@fzyzcjy good point, I have forgotten that Dart_PostCObject
can fail. Changed the example above.
It also would be nice to note why we have both peer
and data
?
@rustonaut I guess data
is for the real data, while peer
is for your arbitrary usage. For example, you may assign another data structure to the peer
in order to do fancy things in the callback. (Just a guess, I am not an expert)
Thanks, I wasn't sure if peer
might be related to e.g. some RPC functionality.
If it's "just a void pointer passed to the finalizer" that would be grate as it would allow me to remove one indirection and simplify the usage in dart, too :+1:
Users struggle to find effecient ways to pass large buffers of data around without either leaking them or copying them multiple times. We should consider providing some primitives and/or samples in FFI.
A common question is: my worker isolate produced large data array which I am holding by a pointer - how do I send it to main isolate without copying or leaking it?
The best answer right now is to use
Dart_PostCObject
to send it as an external typed data and simultaneously assign a finalizer to it - but this approach is not very discoverable. We could consider adding samples or helpers for it.