// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include #include #include #include namespace asio { class io_context; } namespace zen { /// Async process exit watcher. /// /// Uses platform-specific mechanisms for scalable, non-polling exit detection: /// Linux: pidfd_open() + asio::posix::stream_descriptor /// Windows: asio::windows::object_handle /// macOS: kqueue EVFILT_PROC/NOTE_EXIT + asio::posix::stream_descriptor /// /// The callback is invoked exactly once when the process exits, posted to the /// io_context. Call Cancel() to suppress the callback. class ProcessExitWatcher { public: explicit ProcessExitWatcher(asio::io_context& IoContext); ~ProcessExitWatcher(); ProcessExitWatcher(const ProcessExitWatcher&) = delete; ProcessExitWatcher& operator=(const ProcessExitWatcher&) = delete; /// Begin watching the given process. The callback is posted to the io_context /// when the process exits. Only one Watch() may be active at a time. void Watch(const ProcessHandle& Handle, std::function OnExit); /// Cancel any outstanding watch. The callback will not be invoked after this /// returns. Safe to call if no watch is active. void Cancel(); private: struct Impl; std::unique_ptr m_Impl; }; } // namespace zen