Files
react-native/ReactCommon/fabric/mounting/ShadowTreeRegistry.cpp
T
Joshua Gross 90287ca536 Make ShadowTreeRegistry remove API safer
Summary:
Currently the `remove` API returns an owned unique_ptr of the removed ShadowTree but it's not used anywhere, so we can simplify the API.

Because of that change, we can make the API safe even if the SurfaceId has already been removed.

For context, on Android there is a race between RootView.unmountReactApplication and C++ teardown which removes all SurfaceIds. This currently causes a crash, but after this diff the 2nd call to `remove` for a given SurfaceId will noop.

Changelog: [Internal]

Reviewed By: sammy-SC

Differential Revision: D22416471

fbshipit-source-id: dbba44c276aab8e81097b92a89e0becdcb7b28ba
2020-07-07 13:01:47 -07:00

63 lines
1.5 KiB
C++

/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include "ShadowTreeRegistry.h"
namespace facebook {
namespace react {
ShadowTreeRegistry::~ShadowTreeRegistry() {
assert(
registry_.empty() && "Deallocation of non-empty `ShadowTreeRegistry`.");
}
void ShadowTreeRegistry::add(std::unique_ptr<ShadowTree> &&shadowTree) const {
std::unique_lock<better::shared_mutex> lock(mutex_);
registry_.emplace(shadowTree->getSurfaceId(), std::move(shadowTree));
}
void ShadowTreeRegistry::remove(SurfaceId surfaceId) const {
std::unique_lock<better::shared_mutex> lock(mutex_);
auto iterator = registry_.find(surfaceId);
if (iterator != registry_.end()) {
registry_.erase(iterator);
}
}
bool ShadowTreeRegistry::visit(
SurfaceId surfaceId,
std::function<void(const ShadowTree &shadowTree)> callback) const {
std::shared_lock<better::shared_mutex> lock(mutex_);
auto iterator = registry_.find(surfaceId);
if (iterator == registry_.end()) {
return false;
}
callback(*iterator->second);
return true;
}
void ShadowTreeRegistry::enumerate(
std::function<void(const ShadowTree &shadowTree, bool &stop)> callback)
const {
std::shared_lock<better::shared_mutex> lock(mutex_);
bool stop = false;
for (auto const &pair : registry_) {
callback(*pair.second, stop);
if (stop) {
break;
}
}
}
} // namespace react
} // namespace facebook