Skip to content

Commit 31f5aef

Browse files
committed
fix(android): crash concurrent access _registryByName (#117)
* fix(android): crash happening because _registryByName isn't properly lock guarded * fix this pointer pointing to destructed class in thread
1 parent 7efce00 commit 31f5aef

File tree

2 files changed

+11
-6
lines changed

2 files changed

+11
-6
lines changed

packages/react-native/ReactCommon/react/renderer/componentregistry/ComponentDescriptorRegistry.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,16 @@ void ComponentDescriptorRegistry::addMultipleAsync(
4040
auto parametersCopy = parameters_;
4141
auto contextContainerCopy = contextContainer_;
4242

43-
// Start thread immediately
44-
std::thread([this, providers = std::move(providers), parametersCopy, contextContainerCopy]() {
43+
auto self = shared_from_this();
44+
45+
// Start detached thread - registry stays alive until completion due to strong self reference
46+
std::thread([self, providers = std::move(providers), parametersCopy, contextContainerCopy]() {
4547
// Ensure this C++ thread is attached to the JVM before touching JNI
4648
#ifdef __ANDROID__
4749
facebook::jni::Environment::ensureCurrentThreadIsAttached();
4850
#endif
49-
std::unique_lock lock(mutex_);
51+
52+
std::unique_lock lock(self->mutex_);
5053

5154
for (const auto& provider : providers) {
5255
auto componentDescriptor = provider.constructor(
@@ -60,8 +63,8 @@ void ComponentDescriptorRegistry::addMultipleAsync(
6063
auto sharedComponentDescriptor =
6164
std::shared_ptr<const ComponentDescriptor>(std::move(componentDescriptor));
6265

63-
_registryByHandle[provider.handle] = sharedComponentDescriptor;
64-
_registryByName[provider.name] = sharedComponentDescriptor;
66+
self->_registryByHandle[provider.handle] = sharedComponentDescriptor;
67+
self->_registryByName[provider.name] = sharedComponentDescriptor;
6568
}
6669
}).detach();
6770
}
@@ -90,6 +93,8 @@ void ComponentDescriptorRegistry::add(
9093

9194
void ComponentDescriptorRegistry::registerComponentDescriptor(
9295
const SharedComponentDescriptor& componentDescriptor) const {
96+
std::unique_lock lock(mutex_);
97+
9398
ComponentHandle componentHandle = componentDescriptor->getComponentHandle();
9499
_registryByHandle[componentHandle] = componentDescriptor;
95100

packages/react-native/ReactCommon/react/renderer/componentregistry/ComponentDescriptorRegistry.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ using SharedComponentDescriptorRegistry =
2727
/*
2828
* Registry of particular `ComponentDescriptor`s.
2929
*/
30-
class ComponentDescriptorRegistry {
30+
class ComponentDescriptorRegistry : public std::enable_shared_from_this<ComponentDescriptorRegistry> {
3131
public:
3232
using Shared = std::shared_ptr<const ComponentDescriptorRegistry>;
3333

0 commit comments

Comments
 (0)