diff --git a/ReactCommon/fabric/events/EventQueue.cpp b/ReactCommon/fabric/events/EventQueue.cpp index f9f970b0c7a..01a9ef688e1 100644 --- a/ReactCommon/fabric/events/EventQueue.cpp +++ b/ReactCommon/fabric/events/EventQueue.cpp @@ -53,6 +53,13 @@ void EventQueue::onBeat(jsi::Runtime &runtime) const { eventPipe_( runtime, event.eventTarget.get(), event.type, event.payloadFactory); } + + // No need to lock `EventEmitter::DispatchMutex()` here. + for (const auto &event : queue) { + if (event.eventTarget) { + event.eventTarget->release(runtime); + } + } } } // namespace react diff --git a/ReactCommon/fabric/events/EventTarget.cpp b/ReactCommon/fabric/events/EventTarget.cpp index 64dc2549056..112ca5688a8 100644 --- a/ReactCommon/fabric/events/EventTarget.cpp +++ b/ReactCommon/fabric/events/EventTarget.cpp @@ -42,11 +42,20 @@ void EventTarget::retain(jsi::Runtime &runtime) const { assert(!strongInstanceHandle_.isUndefined()); } -jsi::Value EventTarget::release(jsi::Runtime &runtime) const { +void EventTarget::release(jsi::Runtime &runtime) const { // The method does not use `jsi::Runtime` reference. // It takes it only to ensure thread-safety (if the caller has the reference, // we are on a proper thread). - return std::move(strongInstanceHandle_); + strongInstanceHandle_ = jsi::Value::null(); +} + +jsi::Value EventTarget::getInstanceHandle(jsi::Runtime &runtime) const { + if (strongInstanceHandle_.isNull()) { + // The `instanceHandle` is not retained. + return jsi::Value::null(); + } + + return jsi::Value(runtime, strongInstanceHandle_); } Tag EventTarget::getTag() const { diff --git a/ReactCommon/fabric/events/EventTarget.h b/ReactCommon/fabric/events/EventTarget.h index 5a4cf0ae4cd..7567d994e9e 100644 --- a/ReactCommon/fabric/events/EventTarget.h +++ b/ReactCommon/fabric/events/EventTarget.h @@ -43,16 +43,21 @@ class EventTarget { void setEnabled(bool enabled) const; /* - * Creates a strong instance handle from a weak one and stores it inside the - * object. + * Retains an instance handler by creating a strong reference to it. * If the EventTarget is disabled, does nothing. */ void retain(jsi::Runtime &runtime) const; /* - * Extract the stored strong instance handle from the object and returns it. + * Releases the instance handler by nulling a strong reference to it. */ - jsi::Value release(jsi::Runtime &runtime) const; + void release(jsi::Runtime &runtime) const; + + /* + * Creates and returns the `instanceHandle`. + * Returns `null` if the `instanceHandle` is not retained at this moment. + */ + jsi::Value getInstanceHandle(jsi::Runtime &runtime) const; /* * Deprecated. Do not use. diff --git a/ReactCommon/fabric/uimanager/UIManagerBinding.cpp b/ReactCommon/fabric/uimanager/UIManagerBinding.cpp index cc3fe326bd4..0b787b74ddf 100644 --- a/ReactCommon/fabric/uimanager/UIManagerBinding.cpp +++ b/ReactCommon/fabric/uimanager/UIManagerBinding.cpp @@ -74,7 +74,7 @@ void UIManagerBinding::dispatchEvent( auto instanceHandle = eventTarget ? [&]() { - auto instanceHandle = eventTarget->release(runtime); + auto instanceHandle = eventTarget->getInstanceHandle(runtime); if (instanceHandle.isUndefined()) { return jsi::Value::null(); }