• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // 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 LIBBRILLO_BRILLO_PROCESS_REAPER_H_
6 #define LIBBRILLO_BRILLO_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 <brillo/asynchronous_signal_handler.h>
16 #include <brillo/daemons/daemon.h>
17 
18 namespace brillo {
19 
20 class BRILLO_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
29   // brillo::AsynchronousSignalHandlerInterface. You can call Unregister() to
30   // remove this ProcessReapper or it will be called during shutdown.
31   // You can only register this ProcessReaper with one signal handler at a time.
32   void Register(AsynchronousSignalHandlerInterface* async_signal_handler);
33 
34   // Unregisters the ProcessReaper from the
35   // brillo::AsynchronousSignalHandlerInterface passed in Register(). It
36   // doesn't do anything if not registered.
37   void Unregister();
38 
39   // Watch for the child process |pid| to finish and call |callback| when the
40   // selected process exits or the process terminates for other reason. The
41   // |callback| receives the exit status and exit code of the terminated process
42   // as a siginfo_t. See wait(2) for details about siginfo_t.
43   bool WatchForChild(const tracked_objects::Location& from_here,
44                      pid_t pid,
45                      const ChildCallback& callback);
46 
47   // Stop watching child process |pid|.  This is useful in situations
48   // where the child process may have been reaped outside of the signal
49   // handler, or the caller is no longer interested in being notified about
50   // this child process anymore.  Returns true if a child was removed from
51   // the watchlist.
52   bool ForgetChild(pid_t pid);
53 
54  private:
55   // SIGCHLD handler for the AsynchronousSignalHandler. Always returns false
56   // (meaning that the signal handler should not be unregistered).
57   bool HandleSIGCHLD(const signalfd_siginfo& sigfd_info);
58 
59   struct WatchedProcess {
60     tracked_objects::Location location;
61     ChildCallback callback;
62   };
63   std::map<pid_t, WatchedProcess> watched_processes_;
64 
65   // The |async_signal_handler_| is owned by the caller and is |nullptr| when
66   // not registered.
67   AsynchronousSignalHandlerInterface* async_signal_handler_{nullptr};
68 
69   DISALLOW_COPY_AND_ASSIGN(ProcessReaper);
70 };
71 
72 }  // namespace brillo
73 
74 #endif  // LIBBRILLO_BRILLO_PROCESS_REAPER_H_
75