Skip to content

Commit 33cd751

Browse files
authored
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 8af23c9 commit 33cd751

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
@@ -39,13 +39,16 @@ void ComponentDescriptorRegistry::addMultipleAsync(
3939
auto parametersCopy = parameters_;
4040
auto contextContainerCopy = contextContainer_;
4141

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

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

62-
_registryByHandle[provider.handle] = sharedComponentDescriptor;
63-
_registryByName[provider.name] = sharedComponentDescriptor;
65+
self->_registryByHandle[provider.handle] = sharedComponentDescriptor;
66+
self->_registryByName[provider.name] = sharedComponentDescriptor;
6467
}
6568
}).detach();
6669
}
@@ -89,6 +92,8 @@ void ComponentDescriptorRegistry::add(
8992

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

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)