blob: 9dbafe265322692a5a3d058bb372cf181be973b5 [file] [log] [blame]
// Copyright 2016 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef PATCHPANEL_SUBPROCESS_CONTROLLER_H_
#define PATCHPANEL_SUBPROCESS_CONTROLLER_H_
#include <sys/types.h>
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include <base/files/file_path.h>
#include <base/files/scoped_file.h>
#include <base/functional/callback.h>
#include <base/memory/weak_ptr.h>
#include "patchpanel/ipc.h"
#include "patchpanel/message_dispatcher.h"
namespace shill {
class ProcessManager;
} // namespace shill
namespace patchpanel {
class System;
// Tracks a helper subprocess. Handles forking, cleaning up on termination,
// and IPC.
// This object is used by the main Manager process.
class SubprocessController {
public:
// The caller should guarantee the |system| and |process_manager| outlive
// the SubprocessController instance.
SubprocessController(System* system,
shill::ProcessManager* process_manager,
const base::FilePath& cmd_path,
const std::string& fd_arg);
SubprocessController(const SubprocessController&) = delete;
SubprocessController& operator=(const SubprocessController&) = delete;
virtual ~SubprocessController();
// Re-execs patchpanel with a new argument: |argv_| + "|fd_arg_|=N", where N
// is the side of |control_fd|. This tells the subprocess to start up a
// different mainloop.
void Start();
// Serializes a protobuf and sends it to the helper process.
void SendControlMessage(const ControlMessage& proto) const;
// Starts listening on messages from subprocess and dispatching them to
// handlers. This function can only be called after that the message loop of
// main process is initialized.
void Listen();
void RegisterFeedbackMessageHandler(
base::RepeatingCallback<void(const FeedbackMessage&)> handler);
private:
// The callback that is called when the subprocess is exited unexpectedly.
// Attempts to restart the subprocess with exponential backoff delay.
void OnProcessExitedUnexpectedly(int exit_status);
void OnMessage(const SubprocessMessage& msg);
base::RepeatingCallback<void(const FeedbackMessage&)> feedback_handler_;
// Used to create the subprocess and watch the subprocess exited unexpectedly.
System* system_;
// The singleton instance which is used to create the subprocess and watch the
// subprocess exited unexpectedly.
shill::ProcessManager* process_manager_;
std::optional<pid_t> pid_ = std::nullopt;
uint8_t restarts_{0};
base::FilePath cmd_path_;
std::vector<std::string> argv_;
std::string fd_arg_;
std::unique_ptr<MessageDispatcher<SubprocessMessage>> msg_dispatcher_;
base::WeakPtrFactory<SubprocessController> weak_factory_{this};
};
} // namespace patchpanel
#endif // PATCHPANEL_SUBPROCESS_CONTROLLER_H_