blob: 1e69055f1f3618655229c53507388f79ae4ec583 [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
5#ifndef LIBCHROMEOS_CHROMEOS_PROCESS_REAPER_H_
6#define LIBCHROMEOS_CHROMEOS_PROCESS_REAPER_H_
7
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>
15#include <chromeos/asynchronous_signal_handler.h>
16#include <chromeos/daemons/daemon.h>
17
18namespace chromeos {
19
20class CHROMEOS_EXPORT ProcessReaper final {
21 public:
22 // The callback called when a child exits.
23 using ChildCallback = base::Callback<void(const siginfo_t&)>;
24
25 ProcessReaper() = default;
26 ~ProcessReaper();
27
28 // Register the ProcessReaper using either the provided chromeos::Daemon or
29 // chromeos::AsynchronousSignalHandler. You can call Unregister() to remove
30 // this ProcessReapper or it will be called during shutdown.
31 void RegisterWithAsynchronousSignalHandler(
32 AsynchronousSignalHandler* async_signal_handler);
33 void RegisterWithDaemon(Daemon* daemon);
34
35 // Unregisters the ProcessReaper from the chromeos::Daemon or
36 // chromeos::AsynchronousSignalHandler passed in RegisterWith*(). It doesn't
37 // do anything if not registered.
38 void Unregister();
39
40 // Watch for the child process |pid| to finish and call |callback| when the
41 // selected process exits or the process terminates for other reason. The
42 // |callback| receives the exit status and exit code of the terminated process
43 // as a siginfo_t. See wait(2) for details about siginfo_t.
44 bool WatchForChild(const tracked_objects::Location& from_here,
45 pid_t pid,
46 const ChildCallback& callback);
47
48 private:
49 // SIGCHLD handler for the AsynchronousSignalHandler. Always returns false
50 // (meaning that the signal handler should not be unregistered).
51 bool HandleSIGCHLD(const signalfd_siginfo& sigfd_info);
52
53 struct WatchedProcess {
54 tracked_objects::Location location;
55 ChildCallback callback;
56 };
57 std::map<pid_t, WatchedProcess> watched_processes_;
58
59 // Whether the ProcessReaper already registered a signal.
60 bool registered_{false};
61
62 // The |async_signal_handler_| and |daemon_| are owned by the caller and only
63 // one of them is not nullptr.
64 AsynchronousSignalHandler* async_signal_handler_{nullptr};
65 Daemon* daemon_{nullptr};
66
67 DISALLOW_COPY_AND_ASSIGN(ProcessReaper);
68};
69
70} // namespace chromeos
71
72#endif // LIBCHROMEOS_CHROMEOS_PROCESS_REAPER_H_