Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -145,18 +145,6 @@ RuntimeAgent::~RuntimeAgent() {
sessionState_.lastRuntimeAgentExportedState = getExportedState();
}

void RuntimeAgent::enableSamplingProfiler() {
targetController_.enableSamplingProfiler();
}

void RuntimeAgent::disableSamplingProfiler() {
targetController_.disableSamplingProfiler();
}

tracing::RuntimeSamplingProfile RuntimeAgent::collectSamplingProfile() {
return targetController_.collectSamplingProfile();
}

#pragma mark - Tracing

RuntimeTracingAgent::RuntimeTracingAgent(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,21 +85,6 @@ class RuntimeAgent final {
*/
ExportedState getExportedState();

/**
* Start sampling profiler for the corresponding RuntimeTarget.
*/
void enableSamplingProfiler();

/**
* Stop sampling profiler for the corresponding RuntimeTarget.
*/
void disableSamplingProfiler();

/**
* Return recorded sampling profile for the previous sampling session.
*/
tracing::RuntimeSamplingProfile collectSamplingProfile();

private:
FrontendChannel frontendChannel_;
RuntimeTargetController& targetController_;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,40 +179,71 @@ void RuntimeTarget::notifyDomainStateChanged(
Domain domain,
bool enabled,
const RuntimeAgent& notifyingAgent) {
bool runtimeAndLogStatusBefore = false, runtimeAndLogStatusAfter = false;
if (domain == Domain::Log || domain == Domain::Runtime) {
runtimeAndLogStatusBefore =
agentsByEnabledDomain_[Domain::Runtime].contains(&notifyingAgent) &&
agentsByEnabledDomain_[Domain::Log].contains(&notifyingAgent);
}

if (enabled) {
agentsByEnabledDomain_[domain].insert(&notifyingAgent);
} else {
agentsByEnabledDomain_[domain].erase(&notifyingAgent);
}
threadSafeDomainStatus_[domain] = !agentsByEnabledDomain_[domain].empty();

if (domain == Domain::Log || domain == Domain::Runtime) {
runtimeAndLogStatusAfter =
agentsByEnabledDomain_[Domain::Runtime].contains(&notifyingAgent) &&
agentsByEnabledDomain_[Domain::Log].contains(&notifyingAgent);
auto [domainStateChangedLocally, domainStateChangedGlobally] =
processDomainChange(domain, enabled, notifyingAgent);

switch (domain) {
case Domain::Log:
case Domain::Runtime: {
auto otherDomain = domain == Domain::Log ? Domain::Runtime : Domain::Log;
// There should be an agent that enables both Log and Runtime domains.
if (!agentsByEnabledDomain_[otherDomain].contains(&notifyingAgent)) {
break;
}

if (runtimeAndLogStatusBefore != runtimeAndLogStatusAfter) {
if (runtimeAndLogStatusAfter) {
if (domainStateChangedGlobally && enabled) {
assert(agentsWithRuntimeAndLogDomainsEnabled_ == 0);
emitDebuggerSessionCreated();
++agentsWithRuntimeAndLogDomainsEnabled_;
} else if (domainStateChangedGlobally) {
assert(agentsWithRuntimeAndLogDomainsEnabled_ == 1);
emitDebuggerSessionDestroyed();
--agentsWithRuntimeAndLogDomainsEnabled_;
} else if (domainStateChangedLocally && enabled) {
// This is a case when given domain was already enabled by other Agent,
// so global state didn't change.
if (++agentsWithRuntimeAndLogDomainsEnabled_ == 1) {
emitDebuggerSessionCreated();
}
} else {
assert(agentsWithRuntimeAndLogDomainsEnabled_ > 0);
} else if (domainStateChangedLocally) {
if (--agentsWithRuntimeAndLogDomainsEnabled_ == 0) {
emitDebuggerSessionDestroyed();
}
}

break;
}
case Domain::Network:
break;
case Domain::kMaxValue: {
throw std::logic_error("Unexpected kMaxValue domain value provided");
}
}
}

std::pair<bool, bool> RuntimeTarget::processDomainChange(
Domain domain,
bool enabled,
const RuntimeAgent& notifyingAgent) {
bool domainHadAgentsBefore = !agentsByEnabledDomain_[domain].empty();
bool domainHasBeenEnabledBefore =
agentsByEnabledDomain_[domain].contains(&notifyingAgent);

if (enabled) {
agentsByEnabledDomain_[domain].insert(&notifyingAgent);
} else {
agentsByEnabledDomain_[domain].erase(&notifyingAgent);
}
threadSafeDomainStatus_[domain] = !agentsByEnabledDomain_[domain].empty();

bool domainHasAgentsAfter = !agentsByEnabledDomain_[domain].empty();

return {
domainHasBeenEnabledBefore ^ enabled,
domainHadAgentsBefore ^ domainHasAgentsAfter,
};
}

bool RuntimeTarget::isDomainEnabled(Domain domain) const {
return threadSafeDomainStatus_[domain];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <jsinspector-modern/tracing/TraceRecordingState.h>

#include <memory>
#include <utility>

#ifndef JSINSPECTOR_EXPORT
#ifdef _MSC_VER
Expand Down Expand Up @@ -122,7 +123,7 @@ class RuntimeTargetDelegate {
*/
class RuntimeTargetController {
public:
enum class Domain { Network, Runtime, Log, kMaxValue };
enum class Domain { Log, Network, Runtime, kMaxValue };

explicit RuntimeTargetController(RuntimeTarget& target);

Expand Down Expand Up @@ -347,6 +348,22 @@ class JSINSPECTOR_EXPORT RuntimeTarget
bool enabled,
const RuntimeAgent& notifyingAgent);

/**
* Processes the changes to the state of a given domain.
*
* Returns a pair of booleans:
* 1. Returns true, if an only if the given domain state changed locally,
* for a given session.
* 2. Returns true, if and only if the given domain state changed globally:
* when the given Agent is the only Agent that enabled given domain across
* sessions, or when the only Agent that had this domain enabled has
* disconnected.
*/
std::pair<bool, bool> processDomainChange(
Domain domain,
bool enabled,
const RuntimeAgent& notifyingAgent);

/**
* Checks whether the given domain is enabled in at least one session
* that is currently connected. This may be called from any thread, with
Expand Down
Loading