liyujie
2025-08-28 867b8b7b729282c7e14e200ca277435329ebe747
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// Copyright 2015 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
 
#ifndef LIBBRILLO_BRILLO_PROCESS_REAPER_H_
#define LIBBRILLO_BRILLO_PROCESS_REAPER_H_
 
#include <sys/wait.h>
 
#include <map>
 
#include <base/callback.h>
#include <base/location.h>
#include <base/macros.h>
#include <brillo/asynchronous_signal_handler.h>
 
namespace brillo {
 
class BRILLO_EXPORT ProcessReaper final {
 public:
  // The callback called when a child exits.
  using ChildCallback = base::Callback<void(const siginfo_t&)>;
 
  ProcessReaper() = default;
  ~ProcessReaper();
 
  // Register the ProcessReaper using either the provided
  // brillo::AsynchronousSignalHandlerInterface. You can call Unregister() to
  // remove this ProcessReapper or it will be called during shutdown.
  // You can only register this ProcessReaper with one signal handler at a time.
  void Register(AsynchronousSignalHandlerInterface* async_signal_handler);
 
  // Unregisters the ProcessReaper from the
  // brillo::AsynchronousSignalHandlerInterface passed in Register(). It
  // doesn't do anything if not registered.
  void Unregister();
 
  // Watch for the child process |pid| to finish and call |callback| when the
  // selected process exits or the process terminates for other reason. The
  // |callback| receives the exit status and exit code of the terminated process
  // as a siginfo_t. See wait(2) for details about siginfo_t.
  bool WatchForChild(const base::Location& from_here,
                     pid_t pid,
                     const ChildCallback& callback);
 
  // Stop watching child process |pid|.  This is useful in situations
  // where the child process may have been reaped outside of the signal
  // handler, or the caller is no longer interested in being notified about
  // this child process anymore.  Returns true if a child was removed from
  // the watchlist.
  bool ForgetChild(pid_t pid);
 
 private:
  // SIGCHLD handler for the AsynchronousSignalHandler. Always returns false
  // (meaning that the signal handler should not be unregistered).
  bool HandleSIGCHLD(const signalfd_siginfo& sigfd_info);
 
  struct WatchedProcess {
    base::Location location;
    ChildCallback callback;
  };
  std::map<pid_t, WatchedProcess> watched_processes_;
 
  // The |async_signal_handler_| is owned by the caller and is |nullptr| when
  // not registered.
  AsynchronousSignalHandlerInterface* async_signal_handler_{nullptr};
 
  DISALLOW_COPY_AND_ASSIGN(ProcessReaper);
};
 
}  // namespace brillo
 
#endif  // LIBBRILLO_BRILLO_PROCESS_REAPER_H_