Open onsmith opened 1 year ago
Right, it's been really fiddly trying to get some semblance of safety into this corner of the API and the pass we made over this for 0.21 did have the unfortunate side effect of making nested critical sections difficult.
Yeah your workaround makes sense. It's a risky footgun in the sense that you can now freely use JNI which is not safe to do inside a critical section, but if you're only using it to create a nested critical section then hopefully that's OK. I don't think there's really any safer workaround currently.
This exception to the rule that you can't use JNI within a critical section but you can create a nested critical section is fiddly to ensure.
One option could be that we just remove the mutable borrow and extend the long list of safety issues you're responsible for, but my general hope was that we might be able to reduce the number of safety issues that need to be dealt with manually.
Maybe we could actually add an API to AutoElementsCritical
(which is holding a mutable borrow of the env) that would let you create a nested critical section from an existing AutoElementsCritical
?
It's maybe a bit funky that you'd have two APIs for essentially the same thing, one via JNIEnv
and then one via AutoElementsCritical
for nesting, but that could let us enforce this awkward rule via the type system fairly neatly I suppose.
In terms of longer term changes - I think it's likely that this corner of the API should evolve still, while there is currently a fairly unwieldy list of documented safety issues that could be good to try and reduce.
With the 0.21 release we had already accumulated quite a few breaking changes in the name of improving safety and I wasn't looking to boil the ocean trying to address every issue that we found when looking at these APIs, and dragging out the release too long.
There was some discussion that we could consider introducing a closure for the critical section to help us tackle some of the other safety issues here (ref: https://github.com/jni-rs/jni-rs/pull/400#issuecomment-1404319714) which would probably be the most significant change I can think of. This isn't being actively looked at yet though, and isn't really a priority for me atm.
If we were to add some way to nest a critical section via AutoElementsCritical
then I guess that would essentially remain compatible with any change to introduce a closure for the critical section.
I think I'd like to put back the mutable borrow of the array itself too if we can implement AsMut<JPrimitiveArray>
via a GlobalRef
that doesn't erase the type of reference it holds.
Happy to hear if you have other thoughts / ideas for iterating this API based on your usage?
Description
I have a Rust library which uses this crate to access two Java arrays at once through nested critical sections. This behavior is explicitly permitted by the JNI spec:
As first predicted by @rib in this comment, the following minimal example no longer compiles as of version 0.21.0, due to the
&mut
reference toJNIEnv
held byget_array_elements_critical()
:Workaround
My current workaround is to
unsafe_clone()
theJNIEnv
inside the critical section block and use the cloned object for one of the critical sections:Questions
get_array_elements_critical()
to make situations like this one work straight out of the box?Thank you!