blob: 937c88c10df86804694607652db3b604962ca577 [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
Alex Vakulenkofed60b02015-10-27 09:53:05 -07005#ifndef LIBBRILLO_BRILLO_PROCESS_REAPER_H_
6#define LIBBRILLO_BRILLO_PROCESS_REAPER_H_
Alex Deymo471776d2015-07-21 16:12:27 -07007
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>
Alex Vakulenko9ed0cab2015-10-12 15:21:28 -070015#include <brillo/asynchronous_signal_handler.h>
16#include <brillo/daemons/daemon.h>
Alex Deymo471776d2015-07-21 16:12:27 -070017
Alex Vakulenko9ed0cab2015-10-12 15:21:28 -070018namespace brillo {
Alex Deymo471776d2015-07-21 16:12:27 -070019
Alex Vakulenko9ed0cab2015-10-12 15:21:28 -070020class BRILLO_EXPORT ProcessReaper final {
Alex Deymo471776d2015-07-21 16:12:27 -070021 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
Alex Deymo38c16332015-07-27 14:08:34 -070028 // Register the ProcessReaper using either the provided
Alex Vakulenko9ed0cab2015-10-12 15:21:28 -070029 // brillo::AsynchronousSignalHandlerInterface. You can call Unregister() to
Alex Deymo38c16332015-07-27 14:08:34 -070030 // 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);
Alex Deymo471776d2015-07-21 16:12:27 -070033
Alex Deymo38c16332015-07-27 14:08:34 -070034 // Unregisters the ProcessReaper from the
Alex Vakulenko9ed0cab2015-10-12 15:21:28 -070035 // brillo::AsynchronousSignalHandlerInterface passed in Register(). It
Alex Deymo38c16332015-07-27 14:08:34 -070036 // doesn't do anything if not registered.
Alex Deymo471776d2015-07-21 16:12:27 -070037 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
Paul Stewartb6a5c612015-11-18 11:32:22 -080047 // 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
Alex Deymo471776d2015-07-21 16:12:27 -070054 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
Alex Deymo38c16332015-07-27 14:08:34 -070065 // The |async_signal_handler_| is owned by the caller and is |nullptr| when
66 // not registered.
67 AsynchronousSignalHandlerInterface* async_signal_handler_{nullptr};
Alex Deymo471776d2015-07-21 16:12:27 -070068
69 DISALLOW_COPY_AND_ASSIGN(ProcessReaper);
70};
71
Alex Vakulenko9ed0cab2015-10-12 15:21:28 -070072} // namespace brillo
Alex Deymo471776d2015-07-21 16:12:27 -070073
Alex Vakulenkofed60b02015-10-27 09:53:05 -070074#endif // LIBBRILLO_BRILLO_PROCESS_REAPER_H_