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 
     17 namespace brillo {
     18 
     19 class BRILLO_EXPORT ProcessReaper final {
     20  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 
     27   // Register the ProcessReaper using either the provided
     28   // brillo::AsynchronousSignalHandlerInterface. You can call Unregister() to
     29   // 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);
     32 
     33   // Unregisters the ProcessReaper from the
     34   // brillo::AsynchronousSignalHandlerInterface passed in Register(). It
     35   // doesn't do anything if not registered.
     36   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.
     42   bool WatchForChild(const base::Location& from_here,
     43                      pid_t pid,
     44                      const ChildCallback& callback);
     45 
     46   // 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 
     53  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 {
     59     base::Location location;
     60     ChildCallback callback;
     61   };
     62   std::map<pid_t, WatchedProcess> watched_processes_;
     63 
     64   // The |async_signal_handler_| is owned by the caller and is |nullptr| when
     65   // not registered.
     66   AsynchronousSignalHandlerInterface* async_signal_handler_{nullptr};
     67 
     68   DISALLOW_COPY_AND_ASSIGN(ProcessReaper);
     69 };
     70 
     71 }  // namespace brillo
     72 
     73 #endif  // LIBBRILLO_BRILLO_PROCESS_REAPER_H_
     74