Home | History | Annotate | Download | only in brillo
      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