blob: 91b6e4ab79dd178f897ef1ddfd64f49089db3714 [file] [log] [blame]
// Copyright 2023 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/performance/experimental/profiler/process_watcher.h"
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/zx/job.h>
#include <lib/zx/process.h>
#include <lib/zx/result.h>
#include <lib/zx/thread.h>
#include <zircon/types.h>
#include <atomic>
#include <thread>
#include <utility>
#include <gtest/gtest.h>
// Monitor a process and ensure it gets notified when it starts a thread.
//
// Note that the starting thread is paused, but not the starter thread. That ensures we don't
// accidentally deadlock ourself when handling the debug exception.
std::atomic<bool> saw_child;
TEST(ProcessWatcherTests, SelfThreads) {
saw_child = false;
async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);
zx::unowned_process self = zx::process::self();
profiler::ProcessWatcher watcher{
std::move(self),
[](zx_koid_t, zx_koid_t, zx::thread t) { saw_child = true; },
[](zx_koid_t, zx_koid_t) {},
};
std::thread thread_spawner{[]() {
for (;;) {
if (saw_child) {
return;
}
std::thread t([]() { return 0; });
t.join();
}
}};
thread_spawner.detach();
zx::result<> watch_res = watcher.Watch(loop.dispatcher());
ASSERT_TRUE(watch_res.is_ok());
while (!saw_child) {
loop.RunUntilIdle();
}
EXPECT_TRUE(saw_child);
}