blob: beaa7de656d32abfed3a20327b9c95ab625db8ac [file]
/*
* Copyright (C) 2026 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SRC_TRACE_PROCESSOR_RPC_SESSION_LIFECYCLE_H_
#define SRC_TRACE_PROCESSOR_RPC_SESSION_LIFECYCLE_H_
#include <cstdint>
#include <functional>
#include "perfetto/base/build_config.h"
#include "perfetto/base/proc_utils.h"
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
#include <windows.h>
#endif
namespace perfetto::base {
class TaskRunner;
}
namespace perfetto::trace_processor {
// When the server's idle clock applies. Maps to the --idle-start flag.
enum class IdleStart {
// Owner-aware: behave as kOrphaned if launched with a live controlling parent
// (foreground), else as kLastQuery (detached / already orphaned).
kAuto,
// Armed only once the owning parent has exited (the dev-server model).
kOrphaned,
// Always armed; reaps <idle-timeout> after the last request.
kLastQuery,
};
// Tracks whether the process's owning parent (captured at construction) is
// still alive. This is the one OS-specific primitive the lifecycle logic needs:
// "is my owner alive?".
class ProcessOwnerMonitor {
public:
ProcessOwnerMonitor();
~ProcessOwnerMonitor();
ProcessOwnerMonitor(const ProcessOwnerMonitor&) = delete;
ProcessOwnerMonitor& operator=(const ProcessOwnerMonitor&) = delete;
// True if the owning parent captured at construction is still alive.
bool IsOwnerAlive();
// True if there was a live, non-init owning parent at construction (i.e. we
// were launched in the foreground by a real parent, rather than detached or
// already reparented to init).
bool had_owner_at_start() const { return had_owner_at_start_; }
private:
bool had_owner_at_start_ = false;
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
HANDLE parent_handle_ = nullptr;
#else
base::PlatformProcessId owner_pid_ = 0;
#endif
};
// Reaps an idle server. Ticks on the task runner; when the idle clock is armed
// (per IdleStart and owner liveness) and no request has arrived within
// idle_timeout_ms, it invokes on_reap (typically: unlink socket + quit).
class IdleReaper {
public:
// |idle_timeout_ms| == 0 disables reaping entirely (Start() is a no-op).
IdleReaper(base::TaskRunner* task_runner,
uint32_t idle_timeout_ms,
IdleStart idle_start,
std::function<void()> on_reap);
// Begins periodic ticking. Call once after the server is ready.
void Start();
// Resets the idle clock. Call at the end of handling each request.
void OnActivity();
// True while a request is being processed; reaping is suppressed.
void set_query_in_flight(bool v) { query_in_flight_ = v; }
private:
void Tick();
base::TaskRunner* const task_runner_;
const uint32_t idle_timeout_ms_;
const uint32_t tick_interval_ms_;
ProcessOwnerMonitor owner_monitor_;
IdleStart effective_start_;
std::function<void()> on_reap_;
int64_t last_activity_ms_ = 0;
bool query_in_flight_ = false;
bool reaped_ = false;
};
} // namespace perfetto::trace_processor
#endif // SRC_TRACE_PROCESSOR_RPC_SESSION_LIFECYCLE_H_