diff --git a/packages/react-native-reanimated/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.cpp b/packages/react-native-reanimated/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.cpp index 12b4b22fe8b..f92e0fc4ec3 100644 --- a/packages/react-native-reanimated/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.cpp +++ b/packages/react-native-reanimated/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.cpp @@ -4,6 +4,8 @@ #include #include #include +#include +#include #ifdef RCT_NEW_ARCH_ENABLED #include @@ -220,10 +222,55 @@ void ReanimatedModuleProxy::scheduleOnUI( } jsi::Value ReanimatedModuleProxy::executeOnUIRuntimeSync( - jsi::Runtime &rt, - const jsi::Value &worklet) { - return uiWorkletRuntime_->executeSync(rt, worklet); -} + jsi::Runtime &rt, + const jsi::Value &worklet) { + + // Ensure that locking is supported + assert( + supportsLocking_ && + ("[Reanimated] Runtime \"" + name_ + "\" doesn't support locking.") + .c_str()); + + // Extract the shareable worklet, throwing an error if invalid + auto shareableWorklet = extractShareableOrThrow( + rt, + worklet, + "[Reanimated] Only worklets can be executed synchronously on the UI runtime."); + + // Synchronization primitives + std::mutex mutex; + std::condition_variable cv; + bool taskCompleted = false; + std::shared_ptr shareableResult; + + // Schedule the worklet on the UI thread + uiScheduler_->scheduleOnUI([&] { + + // Execute the worklet within the UI runtime + + auto result = uiWorkletRuntime_->runGuarded(shareableWorklet); + shareableResult = extractShareableOrThrow(uiWorkletRuntime_->getJSIRuntime(), result); + + + // Lock the mutex, store the result, and notify the waiting thread + { + std::lock_guard lock(mutex); + taskCompleted = true; + } + cv.notify_one(); + }); + + // Wait for the UI thread to complete the task + { + std::unique_lock lock(mutex); + cv.wait(lock, [&]() { return taskCompleted; }); + } + + jsi::Value workletResult = shareableResult->toJSValue(rt); + + // Return the result to the calling thread + return workletResult; + } jsi::Value ReanimatedModuleProxy::createWorkletRuntime( jsi::Runtime &rt,