From 44160204e2c80808b70ffc49b89345cfdaa44838 Mon Sep 17 00:00:00 2001 From: modeco80 Date: Fri, 2 Feb 2024 05:50:08 -0500 Subject: [PATCH] Begin implementing nanosm main logic --- README.md | 6 ++++- doc/nanosm.toml | 12 +++------ src/Process.cpp | 2 +- src/Timer.hpp | 5 ++++ src/main.cpp | 69 +++++++++++++++++++++++++++++++++++++------------ 5 files changed, 67 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index c2fde19..ab6b7a4 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,11 @@ A more robust solution that's still small and easy to setup (read: Not written i # Installation -TODO +```bash +$ cmake -Wno-dev -GNinja -Bbuild -DCMAKE_INSTALL_PREFIX=/usr +$ ninja -C build +# ninja -C build install +``` # Configuration diff --git a/doc/nanosm.toml b/doc/nanosm.toml index c153599..74efa77 100644 --- a/doc/nanosm.toml +++ b/doc/nanosm.toml @@ -2,17 +2,13 @@ [nanosm] -# Controls if nanosm should be more verbose. Defaults to false. -verbose = false - -# The time in seconds nanosm will wait before restarting any app which exits. +# The time in seconds nanosm will wait before restarting any app which crashes. restart-time = 1 - # Any applications you want to run at startup. -# Note that applications are executed in the order they are declared, but -# this will not hold true if any (or all apps) crash (they will be restarted -# effectively in a psuedorandom order). +# Note that applications are executed in the order they are declared +# only once they are first started, and will from then on start in the +# order that they happen to crash. This may not be great but is how it be for now. [nanosm.apps] # The window manager you want to use. window-manager = { command = "/path/to/wm/binary --any-additional-args-here" } diff --git a/src/Process.cpp b/src/Process.cpp index 660cacb..265fe46 100644 --- a/src/Process.cpp +++ b/src/Process.cpp @@ -51,7 +51,7 @@ namespace nanosm { execvp(exp.words[0].data(), argv.data()); } else { - // Parent: monitor FD + // Parent: monitor the pidfd by adding ourselves to the event loop now eventLoop.AddObject(IoObject::Ptr(shared_from_this())); if(onProcessSpawn) eventLoop.Post(onProcessSpawn); diff --git a/src/Timer.hpp b/src/Timer.hpp index 4ee37d1..1de9865 100644 --- a/src/Timer.hpp +++ b/src/Timer.hpp @@ -3,6 +3,7 @@ namespace nanosm { + /// A timerfd backed timer. Is always oneshot. struct Timer : nanosm::EventLoop::IoObject, std::enable_shared_from_this { Timer(nanosm::EventLoop& ev); @@ -15,8 +16,12 @@ namespace nanosm { void OnReady(int eventMask) override; + /// Set the callback used to notify when the timer expires. void SetExpiryCallback(std::function expire); + + /// Arm and start the timer. void Arm(u32 durationSeconds); + private: int timerFd { -1 }; std::function cb; diff --git a/src/main.cpp b/src/main.cpp index c5e4429..a283b1d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,33 +1,68 @@ #include +#include #include #include "EventLoop.hpp" -#include "Process.hpp" #include "RestartingProcess.hpp" -#include "Timer.hpp" -nanosm::EventLoop ev; +struct NanoSm { + struct App : std::enable_shared_from_this { + App(nanosm::EventLoop& ev, const std::string& tomlId, const std::string& commandLine) + : process(std::make_shared(ev)), + id(tomlId), + commandLine(commandLine) { + } -auto process = std::make_shared(ev); + void Spawn() { + process->SetSpawnCallback([self = shared_from_this()](pid_t pid) { + printf("\"%s\": command spawned as pid %d successfully\n", self->id.c_str(), pid); -// tests stuff :) -void test() { - process->SetSpawnCallback([](pid_t pid) { - printf("\"%s\" spawned as pid %d successfully\n", process->GetCommandLine().c_str(), pid); - // Do magic - process->SetExitCallback([](pid_t pid, int exitCode) { - printf("\"%s\" pid %d exited with %d exitcode\n", process->GetCommandLine().c_str(), pid, exitCode); + // Set exit callback too + self->process->SetExitCallback([self](pid_t pid, int exitCode) { + printf("\"%s\": pid %d exited with %d exitcode\n", self->id.c_str(), pid, exitCode); + }); + }); + + process->Spawn(commandLine); + } + + private: + std::shared_ptr process; + std::string id; + std::string commandLine; + }; + + void AddApp(const std::string& id, const std::string& cmdLine) { + apps.push_back(std::make_shared(ev, id, cmdLine)); + } + + void SpawnAllApps() { + for(auto& app : apps) + app->Spawn(); + } + + int Run() { + ev.Post([this]() { + this->SpawnAllApps(); }); - }); - process->Spawn("xterm"); -} + ev.Run(); + return 0; + } + + private: + nanosm::EventLoop ev; + std::vector> apps; +}; int main(int argc, char** argv) { - ev.Post(test); + NanoSm nanosm; - ev.Run(); - return 0; + // Run a few hardcoded apps (as a test) + nanosm.AddApp("Xterm", "xterm"); + nanosm.AddApp("Xterm2", "xterm"); + + return nanosm.Run(); }