ladybird/Libraries/LibWebView/ProcessMonitor.cpp
Andreas Kling a031d00695 WebContent: Exit cleanly when browser IPC disconnects
Exit WebContent immediately when either browser-side IPC peer
disconnects. Plumb Unix process exit status through LibWebView so the
browser process can tell clean owner-driven shutdown apart from renderer
crashes.

This keeps nonzero exits and signal deaths reported as crashes, while
letting status 0 exits disappear without making test-web report the page
as crashed.
2026-05-12 20:57:08 +02:00

59 lines
1.6 KiB
C++

/*
* Copyright (c) 2025, ayeteadoe <ayeteadoe@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibCore/EventLoop.h>
#include <LibWebView/ProcessMonitor.h>
#if !defined(AK_OS_WINDOWS)
# include <LibCore/System.h>
#endif
namespace WebView {
ProcessMonitor::ProcessMonitor(Function<void(pid_t, Optional<int> exit_status)> exit_handler)
: m_on_process_exit(move(exit_handler))
{
#if !defined(AK_OS_WINDOWS)
m_signal_handle = Core::EventLoop::register_signal(SIGCHLD, [this](int) {
auto result = Core::System::waitpid(-1, WNOHANG);
while (!result.is_error() && result.value().pid > 0) {
auto& [pid, status] = result.value();
if (m_monitored_processes.contains(pid)) {
if (WIFEXITED(status) || WIFSIGNALED(status)) {
m_monitored_processes.remove(pid);
m_on_process_exit(pid, status);
}
}
result = Core::System::waitpid(-1, WNOHANG);
}
});
#endif
}
ProcessMonitor::~ProcessMonitor()
{
#if defined(AK_OS_WINDOWS)
for (pid_t pid : m_monitored_processes) {
Core::EventLoop::unregister_process(pid);
}
#else
Core::EventLoop::unregister_signal(m_signal_handle);
#endif
}
void ProcessMonitor::add_process(pid_t pid)
{
if (m_monitored_processes.set(pid, AK::HashSetExistingEntryBehavior::Keep) != AK::HashSetResult::InsertedNewEntry)
return;
#if defined(AK_OS_WINDOWS)
Core::EventLoop::register_process(pid, [this](pid_t pid) {
m_monitored_processes.remove(pid);
m_on_process_exit(pid, {});
});
#endif
}
}