Files
react-native/ReactCommon/fabric/mounting/ShadowTreeRegistry.h
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

69 lines
1.9 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.
*/
#pragma once
#include <better/map.h>
#include <better/mutex.h>
#include <react/core/ReactPrimitives.h>
#include <react/mounting/ShadowTree.h>
namespace facebook {
namespace react {
/*
* Owning registry of `ShadowTree`s.
*/
class ShadowTreeRegistry final {
public:
ShadowTreeRegistry() = default;
~ShadowTreeRegistry();
/*
* Adds a `ShadowTree` instance to the registry.
* The ownership of the instance is also transferred to the registry.
* Can be called from any thread.
*/
void add(std::unique_ptr<ShadowTree> &&shadowTree) const;
/*
* Removes a `ShadowTree` instance with given `surfaceId` from the registry
* and returns it as a result.
* Can be called from any thread.
*/
void remove(SurfaceId surfaceId) const;
/*
* Finds a `ShadowTree` instance with a given `surfaceId` in the registry and
* synchronously calls the `callback` with a reference to the instance while
* the mutex is being acquired.
* Returns `true` if the registry has `ShadowTree` instance with corresponding
* `surfaceId`, otherwise returns `false` without calling the `callback`.
* Can be called from any thread.
*/
bool visit(
SurfaceId surfaceId,
std::function<void(const ShadowTree &shadowTree)> callback) const;
/*
* Enumerates all stored shadow trees.
* Set `stop` to `true` to interrupt the enumeration.
* Can be called from any thread.
*/
void enumerate(std::function<void(const ShadowTree &shadowTree, bool &stop)>
callback) const;
private:
mutable better::shared_mutex mutex_;
mutable better::map<SurfaceId, std::unique_ptr<ShadowTree>>
registry_; // Protected by `mutex_`.
};
} // namespace react
} // namespace facebook