Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR adds a test to show crashing behavior. I have a solution ready, but wanted to discuss options first.
The Problem
new_callback
(and by extensionwrap_callback
) take a closure, whose state has to be stored somewhere. Currently, it’s stored in aRefCell
that is leaked viaBox::leak
. However, the closure isFnMut
, which means the closure’s state needs to be mutated.RefCell::borrow_mut
allows this to work by deferring the borrow checks to runtime.However, in a re-entrant scenario (closure is invoked from JS, closure calls back in to JS and JS calls back into the same closure), the runtime borrow checker of
RefCell
will panic. This is, in my opinion, unexpected.Solution
The solution I have tested is to change the closure from
FnMut
toFn
. That way, we can ditch theRefCell
and just useBox::leak
to get a*'static const F
. If a developer wants to mutate state, they can still resort toRefCell
orMutex
or similar mechanisms to do so.If we change the existing APIs, it is arguably a breaking change. Adding new APIs that use
Fn
instead ofFnMut
seems clunky but allows backwards compatibility.Open to other suggestions.