Skip to content

Commit

Permalink
fix: Explicitly dereference lambda params in correct thread
Browse files Browse the repository at this point in the history
Instead of letting the lambda destructor destroy instances, we now explicitly set them to nullptr in the same thread as they were created to avoid any shenanigans and crashes when calling destructors from wrong threads.
  • Loading branch information
chrfalch committed Apr 25, 2024
1 parent 7c7f761 commit edc1ae4
Showing 1 changed file with 11 additions and 3 deletions.
14 changes: 11 additions & 3 deletions cpp/WKTJsiWorkletContext.cpp
Expand Up @@ -343,7 +343,7 @@ JsiWorkletContext::createCallInContext(jsi::Runtime &runtime,
// Create callback wrapper
callIntoCorrectContext([callback, workletInvoker, thisWrapper,
argsWrapper, promise,
func](jsi::Runtime &runtime) {
func](jsi::Runtime &runtime) mutable {
try {

auto args = argsWrapper.getArguments(runtime);
Expand Down Expand Up @@ -399,6 +399,10 @@ JsiWorkletContext::createCallInContext(jsi::Runtime &runtime,
runtime, "Unknown error in promise."));
});
}

// We need to explicitly clear the func shared pointer here to avoid it being
// deleted on another thread
promise = nullptr;
});
});

Expand All @@ -417,7 +421,7 @@ JsiWorkletContext::createInvoker(jsi::Runtime &runtime,
func = std::make_shared<jsi::Function>(
maybeFunc->asObject(runtime).asFunction(runtime))](
jsi::Runtime &runtime, const jsi::Value &thisValue,
const jsi::Value *arguments, size_t count) {
const jsi::Value *arguments, size_t count) mutable {
// If we are in the same context let's just call the function directly
if (&runtime == rtPtr) {
return func->call(runtime, arguments, count);
Expand All @@ -439,13 +443,17 @@ JsiWorkletContext::createInvoker(jsi::Runtime &runtime,
});
} else {
JsiWorkletContext::getDefaultInstance()->invokeOnJsThread(
[argsWrapper, rtPtr, func = std::move(func)](jsi::Runtime &runtime) {
[argsWrapper, rtPtr, func](jsi::Runtime &runtime) {
assert(&runtime == rtPtr && "Expected same runtime ptr!");
auto args = argsWrapper.getArguments(runtime);
func->call(runtime, ArgumentsWrapper::toArgs(args),
argsWrapper.getCount());
});
}

// We need to explicitly clear the func shared pointer here to avoid it being
// deleted on another thread
func = nullptr;

return jsi::Value::undefined();
};
Expand Down

1 comment on commit edc1ae4

@mrousavy
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice!

Please sign in to comment.