Skip to content

Commit 48f1f2d

Browse files
motiz88facebook-github-bot
authored andcommitted
RuntimeTarget refactor - Store weak refs to agents in RuntimeTarget
Summary: Changelog: [Internal] Applies to RuntimeTarget → RuntimeAgent the same pattern we use for InstanceTarget → InstanceAgent (D53266708) and PageTarget → PageTargetSession: the target has `weak_ptr`s to its agents/sessions so it can (1) dispatch events to them and (2) assert that they are destroyed before the target itself is destroyed. In RuntimeTarget this will primarily serve as an event dispatching mechanism from JS (single target) to CDP (multiple sessions), with the addition of threading abstractions in upcoming diffs. Reviewed By: hoxyq Differential Revision: D53266706 fbshipit-source-id: 64d7226a1aebf00e0ad178f28101a568e9bc6c53
1 parent 04eadf6 commit 48f1f2d

File tree

3 files changed

+42
-4
lines changed

3 files changed

+42
-4
lines changed

packages/react-native/ReactCommon/jsinspector-modern/InstanceAgent.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ class InstanceAgent final {
5757
private:
5858
FrontendChannel frontendChannel_;
5959
InstanceTarget& target_;
60-
std::unique_ptr<RuntimeAgent> runtimeAgent_;
60+
std::shared_ptr<RuntimeAgent> runtimeAgent_;
6161
SessionState& sessionState_;
6262
};
6363

packages/react-native/ReactCommon/jsinspector-modern/RuntimeTarget.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,31 @@ namespace facebook::react::jsinspector_modern {
1111
RuntimeTarget::RuntimeTarget(RuntimeTargetDelegate& delegate)
1212
: delegate_(delegate) {}
1313

14-
std::unique_ptr<RuntimeAgent> RuntimeTarget::createAgent(
14+
std::shared_ptr<RuntimeAgent> RuntimeTarget::createAgent(
1515
FrontendChannel channel,
1616
SessionState& sessionState) {
17-
return std::make_unique<RuntimeAgent>(
17+
auto runtimeAgent = std::make_shared<RuntimeAgent>(
1818
channel,
1919
*this,
2020
sessionState,
2121
delegate_.createAgentDelegate(channel, sessionState));
22+
agents_.push_back(runtimeAgent);
23+
return runtimeAgent;
24+
}
25+
26+
void RuntimeTarget::removeExpiredAgents() {
27+
// Remove all expired agents.
28+
forEachAgent([](auto&) {});
29+
}
30+
31+
RuntimeTarget::~RuntimeTarget() {
32+
removeExpiredAgents();
33+
34+
// Agents are owned by the session, not by RuntimeTarget, but
35+
// they hold a RuntimeTarget& that we must guarantee is valid.
36+
assert(
37+
agents_.empty() &&
38+
"RuntimeAgent objects must be destroyed before their RuntimeTarget. Did you call InstanceTarget::unregisterRuntime()?");
2239
}
2340

2441
} // namespace facebook::react::jsinspector_modern

packages/react-native/ReactCommon/jsinspector-modern/RuntimeTarget.h

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "RuntimeAgent.h"
1212
#include "SessionState.h"
1313

14+
#include <list>
1415
#include <memory>
1516

1617
#ifndef JSINSPECTOR_EXPORT
@@ -59,6 +60,7 @@ class JSINSPECTOR_EXPORT RuntimeTarget final {
5960
RuntimeTarget(RuntimeTarget&&) = delete;
6061
RuntimeTarget& operator=(const RuntimeTarget&) = delete;
6162
RuntimeTarget& operator=(RuntimeTarget&&) = delete;
63+
~RuntimeTarget();
6264

6365
/**
6466
* Create a new RuntimeAgent that can be used to debug the underlying JS VM.
@@ -69,12 +71,31 @@ class JSINSPECTOR_EXPORT RuntimeTarget final {
6971
* frontend.
7072
* \returns The new agent, or nullptr if the runtime is not debuggable.
7173
*/
72-
std::unique_ptr<RuntimeAgent> createAgent(
74+
std::shared_ptr<RuntimeAgent> createAgent(
7375
FrontendChannel channel,
7476
SessionState& sessionState);
7577

7678
private:
7779
RuntimeTargetDelegate& delegate_;
80+
std::list<std::weak_ptr<RuntimeAgent>> agents_;
81+
82+
/**
83+
* Call the given function for every active agent, and clean up any
84+
* references to inactive agents.
85+
*/
86+
template <typename Fn>
87+
void forEachAgent(Fn&& fn) {
88+
for (auto it = agents_.begin(); it != agents_.end();) {
89+
if (auto agent = it->lock()) {
90+
fn(*agent);
91+
++it;
92+
} else {
93+
it = agents_.erase(it);
94+
}
95+
}
96+
}
97+
98+
void removeExpiredAgents();
7899
};
79100

80101
} // namespace facebook::react::jsinspector_modern

0 commit comments

Comments
 (0)