blob: 7b70a8d6b4bbacbc4e6cd421c96ca6795e9a658c [file] [log] [blame]
Alex Deymo471776d2015-07-21 16:12:27 -07001// Copyright 2015 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Alex Vakulenkofed60b02015-10-27 09:53:05 -07005#ifndef LIBBRILLO_BRILLO_PROCESS_REAPER_H_
6#define LIBBRILLO_BRILLO_PROCESS_REAPER_H_
Alex Deymo471776d2015-07-21 16:12:27 -07007
8#include <sys/wait.h>
9
10#include <map>
11
12#include <base/callback.h>
13#include <base/location.h>
14#include <base/macros.h>
Alex Vakulenko9ed0cab2015-10-12 15:21:28 -070015#include <brillo/asynchronous_signal_handler.h>
Alex Deymo471776d2015-07-21 16:12:27 -070016
Alex Vakulenko9ed0cab2015-10-12 15:21:28 -070017namespace brillo {
Alex Deymo471776d2015-07-21 16:12:27 -070018
Alex Vakulenko9ed0cab2015-10-12 15:21:28 -070019class BRILLO_EXPORT ProcessReaper final {
Alex Deymo471776d2015-07-21 16:12:27 -070020 public:
21 // The callback called when a child exits.
22 using ChildCallback = base::Callback<void(const siginfo_t&)>;
23
24 ProcessReaper() = default;
25 ~ProcessReaper();
26
Alex Deymo38c16332015-07-27 14:08:34 -070027 // Register the ProcessReaper using either the provided
Alex Vakulenko9ed0cab2015-10-12 15:21:28 -070028 // brillo::AsynchronousSignalHandlerInterface. You can call Unregister() to
Alex Deymo38c16332015-07-27 14:08:34 -070029 // remove this ProcessReapper or it will be called during shutdown.
30 // You can only register this ProcessReaper with one signal handler at a time.
31 void Register(AsynchronousSignalHandlerInterface* async_signal_handler);
Alex Deymo471776d2015-07-21 16:12:27 -070032
Alex Deymo38c16332015-07-27 14:08:34 -070033 // Unregisters the ProcessReaper from the
Alex Vakulenko9ed0cab2015-10-12 15:21:28 -070034 // brillo::AsynchronousSignalHandlerInterface passed in Register(). It
Alex Deymo38c16332015-07-27 14:08:34 -070035 // doesn't do anything if not registered.
Alex Deymo471776d2015-07-21 16:12:27 -070036 void Unregister();
37
38 // Watch for the child process |pid| to finish and call |callback| when the
39 // selected process exits or the process terminates for other reason. The
40 // |callback| receives the exit status and exit code of the terminated process
41 // as a siginfo_t. See wait(2) for details about siginfo_t.
Jakub Pawlowskicfd1fbb2018-07-19 13:46:06 -070042 bool WatchForChild(const base::Location& from_here,
Alex Deymo471776d2015-07-21 16:12:27 -070043 pid_t pid,
44 const ChildCallback& callback);
45
Paul Stewartb6a5c612015-11-18 11:32:22 -080046 // Stop watching child process |pid|. This is useful in situations
47 // where the child process may have been reaped outside of the signal
48 // handler, or the caller is no longer interested in being notified about
49 // this child process anymore. Returns true if a child was removed from
50 // the watchlist.
51 bool ForgetChild(pid_t pid);
52
Alex Deymo471776d2015-07-21 16:12:27 -070053 private:
54 // SIGCHLD handler for the AsynchronousSignalHandler. Always returns false
55 // (meaning that the signal handler should not be unregistered).
56 bool HandleSIGCHLD(const signalfd_siginfo& sigfd_info);
57
58 struct WatchedProcess {
Jakub Pawlowskicfd1fbb2018-07-19 13:46:06 -070059 base::Location location;
Alex Deymo471776d2015-07-21 16:12:27 -070060 ChildCallback callback;
61 };
62 std::map<pid_t, WatchedProcess> watched_processes_;
63
Alex Deymo38c16332015-07-27 14:08:34 -070064 // The |async_signal_handler_| is owned by the caller and is |nullptr| when
65 // not registered.
66 AsynchronousSignalHandlerInterface* async_signal_handler_{nullptr};
Alex Deymo471776d2015-07-21 16:12:27 -070067
68 DISALLOW_COPY_AND_ASSIGN(ProcessReaper);
69};
70
Alex Vakulenko9ed0cab2015-10-12 15:21:28 -070071} // namespace brillo
Alex Deymo471776d2015-07-21 16:12:27 -070072
Alex Vakulenkofed60b02015-10-27 09:53:05 -070073#endif // LIBBRILLO_BRILLO_PROCESS_REAPER_H_