blob: a5aa406e10cfb7cd1edeb180fd3109a07314ed64 [file] [log] [blame]
#ifndef AOS_STARTER_STARTERD_LIB_H_
#define AOS_STARTER_STARTERD_LIB_H_
#include <sys/signalfd.h>
#include <csignal>
#include <memory>
#include <mutex>
#include <string>
#include <unordered_map>
#include <vector>
#include "aos/configuration.h"
#include "aos/events/event_loop.h"
#include "aos/events/event_loop_generated.h"
#include "aos/events/shm_event_loop.h"
#include "aos/ftrace.h"
#include "aos/ipc_lib/memory_mapped_queue.h"
#include "aos/macros.h"
#include "aos/starter/starter_generated.h"
#include "aos/starter/starter_rpc_generated.h"
#include "aos/starter/subprocess.h"
#include "aos/util/top.h"
namespace aos::starter {
const aos::Channel *StatusChannelForNode(const aos::Configuration *config,
const aos::Node *node);
const aos::Channel *StarterRpcChannelForNode(const aos::Configuration *config,
const aos::Node *node);
class Starter {
public:
Starter(const aos::Configuration *event_loop_config);
// Inserts a new application from config. Returns the inserted application if
// it was successful, otherwise nullptr if an application already exists
// with the given name.
Application *AddApplication(const aos::Application *application);
// Runs the event loop and starts all applications
void Run();
void Cleanup();
// EventLoop that we use for running the code. Mostly exposed for testing
// purposes.
EventLoop *event_loop() { return &event_loop_; }
private:
// Signals which indicate starter has died
static const inline std::vector<int> kStarterDeath = {
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, SIGFPE,
SIGSEGV, SIGPIPE, SIGTERM, SIGBUS, SIGXCPU};
void OnSignal(signalfd_siginfo signal);
void HandleStarterRpc(const StarterRpc &command);
// Handles any potential state change in the child applications.
// In particular, sends the Status message if it wouldn't exceed the rate
// limit.
void HandleStateChange();
// Called periodically to run through the timing report fetcher and alert all
// the Application's to the new messages.
void ServiceTimingReportFetcher(int elapsed_cycles);
void SendStatus();
// Creates a MemoryMappedQueue for the given channel, to pre-allocate shared
// memory to give this process credit for the memory instead of any other
// process that accesses it.
void AddChannel(const aos::Channel *channel);
const std::string config_path_;
const aos::Configuration *config_msg_;
aos::ShmEventLoop event_loop_;
aos::Sender<aos::starter::Status> status_sender_;
aos::PhasedLoopHandler *status_timer_;
aos::TimerHandler *cleanup_timer_;
aos::Ftrace ftrace_;
int status_count_ = 0;
const int max_status_count_;
aos::Fetcher<aos::timing::Report> timing_report_fetcher_;
std::unordered_map<std::string, Application> applications_;
// Lock and list of all the queues. This makes it so we can initialize the
// queues in parallel, and also so starterd owns the memory for all the
// queues from cgroup's point of view.
std::mutex queue_mutex_;
std::vector<std::unique_ptr<aos::ipc_lib::MemoryMappedQueue>> shm_queues_;
// Capture the --shm_base flag at construction time. This makes it much
// easier to make different shared memory regions for doing things like
// multi-node tests.
std::string shm_base_;
// Set to true on cleanup to block rpc commands and ensure cleanup only
// happens once.
bool exiting_ = false;
SignalListener listener_;
util::Top top_;
DISALLOW_COPY_AND_ASSIGN(Starter);
};
} // namespace aos::starter
#endif // AOS_STARTER_STARTERD_LIB_H_