You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
74 lines
2.6 KiB
74 lines
2.6 KiB
// 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> |
|
#include <brillo/daemons/daemon.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 tracked_objects::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 { |
|
tracked_objects::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_
|
|
|