mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
653d8540c6
Summary: One of the operations we do in `Scheduler::stopSurface()` is committing an empty tree to free up `ShadowNode` objects and "disable" `EventEmitter`s associated with them. Before this change, we had a gap in time between a moment when we commit an empty tree and remove the tree from the registry. During this time gap, JavaScript (or native, actually) can commit another tree and mount another new state on the screen. To prevent this, we remove the tree from the registry first and only then commit an empty tree to a uniquely owned tree. Note that the deleted comment says that we actually have to have a tree in the registry for committing an empty tree, I don't think it's true now. Changelog: [Internal] Fabric-specific internal change. Reviewed By: sammy-SC Differential Revision: D23667882 fbshipit-source-id: 387052e9f3e78e7d4446f36baed50f9caa831133
71 lines
2.1 KiB
C++
71 lines
2.1 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/renderer/core/ReactPrimitives.h>
|
|
#include <react/renderer/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.
|
|
* The ownership of the instance is also transferred to the caller.
|
|
* Returns `nullptr` if a `ShadowTree` with given `surfaceId` was not found.
|
|
* Can be called from any thread.
|
|
*/
|
|
std::unique_ptr<ShadowTree> 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
|