blob: d88f57292689db99033b3dd8a58f5928e2a6aa5f [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
47 private:
48 // SIGCHLD handler for the AsynchronousSignalHandler. Always returns false
49 // (meaning that the signal handler should not be unregistered).
50 bool HandleSIGCHLD(const signalfd_siginfo& sigfd_info);
51
52 struct WatchedProcess {
53 tracked_objects::Location location;
54 ChildCallback callback;
55 };
56 std::map<pid_t, WatchedProcess> watched_processes_;
57
Alex Deymo38c16332015-07-27 14:08:34 -070058 // The |async_signal_handler_| is owned by the caller and is |nullptr| when
59 // not registered.
60 AsynchronousSignalHandlerInterface* async_signal_handler_{nullptr};
Alex Deymo471776d2015-07-21 16:12:27 -070061
62 DISALLOW_COPY_AND_ASSIGN(ProcessReaper);
63};
64
Alex Vakulenko9ed0cab2015-10-12 15:21:28 -070065} // namespace brillo
Alex Deymo471776d2015-07-21 16:12:27 -070066
Alex Vakulenkofed60b02015-10-27 09:53:05 -070067#endif // LIBBRILLO_BRILLO_PROCESS_REAPER_H_