mirror of
https://github.com/oxen-io/lokinet
synced 2023-12-14 06:53:00 +01:00
fix race when initializing context in lokinet main.
when we configure but fail to start up, we can hit a case when we have a context that is configured but not setup or running. when we try to sigterm/sigint we get stuck and cannot exit as the llarp::Context shared_ptr global is nullptr but dangles elsewhere. we make it so that we fufill a promose if we fully configure and setup successfully right before running the event loop main for it. this makes it so we bail if setup was not completed and exit our process.
This commit is contained in:
parent
e3e9b16ddf
commit
eca944c427
2 changed files with 35 additions and 11 deletions
|
@ -1,4 +1,5 @@
|
|||
#include <chrono>
|
||||
#include <exception>
|
||||
#include <llarp/config/config.hpp> // for ensure_config
|
||||
#include <llarp/constants/version.hpp>
|
||||
#include <llarp.hpp>
|
||||
|
@ -7,6 +8,9 @@
|
|||
#include <llarp/util/fs.hpp>
|
||||
#include <llarp/util/str.hpp>
|
||||
|
||||
#include <llarp/router/abstractrouter.hpp>
|
||||
#include <memory>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <llarp/win32/service_manager.hpp>
|
||||
#include <dbghelp.h>
|
||||
|
@ -62,7 +66,10 @@ namespace
|
|||
void
|
||||
handle_signal(int sig);
|
||||
static void
|
||||
run_main_context(std::optional<fs::path> confFile, const llarp::RuntimeOptions opts);
|
||||
run_main_context(
|
||||
std::optional<fs::path> confFile,
|
||||
const llarp::RuntimeOptions opts,
|
||||
std::promise<std::shared_ptr<llarp::Context>>& startup);
|
||||
|
||||
// variable declarations
|
||||
static auto logcat = llarp::log::Cat("main");
|
||||
|
@ -499,7 +506,20 @@ namespace
|
|||
SetUnhandledExceptionFilter(&GenerateDump);
|
||||
#endif
|
||||
|
||||
std::thread main_thread{[configFile, opts] { run_main_context(configFile, opts); }};
|
||||
std::promise<std::shared_ptr<llarp::Context>> startup;
|
||||
|
||||
std::thread main_thread{
|
||||
[configFile, opts, &startup] { run_main_context(configFile, opts, startup); }};
|
||||
try
|
||||
{
|
||||
auto ftr = startup.get_future();
|
||||
ctx = ftr.get();
|
||||
}
|
||||
catch (std::exception& ex)
|
||||
{
|
||||
oxen::log::error(logcat, "startup fail: {}", ex.what());
|
||||
return 1;
|
||||
}
|
||||
auto ftr = exit_code.get_future();
|
||||
|
||||
do
|
||||
|
@ -567,7 +587,10 @@ namespace
|
|||
|
||||
// this sets up, configures and runs the main context
|
||||
static void
|
||||
run_main_context(std::optional<fs::path> confFile, const llarp::RuntimeOptions opts)
|
||||
run_main_context(
|
||||
std::optional<fs::path> confFile,
|
||||
const llarp::RuntimeOptions opts,
|
||||
std::promise<std::shared_ptr<llarp::Context>>& startup)
|
||||
{
|
||||
llarp::LogInfo(fmt::format("starting up {} {}", llarp::VERSION_FULL, llarp::RELEASE_MOTTO));
|
||||
try
|
||||
|
@ -586,14 +609,15 @@ namespace
|
|||
{
|
||||
llarp::LogError("failed to parse configuration");
|
||||
exit_code.set_value(1);
|
||||
startup.set_value(nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
// change cwd to dataDir to support relative paths in config
|
||||
fs::current_path(conf->router.m_dataDir);
|
||||
|
||||
ctx = std::make_shared<llarp::Context>();
|
||||
ctx->Configure(std::move(conf));
|
||||
auto _ctx = std::make_shared<llarp::Context>();
|
||||
_ctx->Configure(std::move(conf));
|
||||
|
||||
signal(SIGINT, handle_signal);
|
||||
signal(SIGTERM, handle_signal);
|
||||
|
@ -605,23 +629,23 @@ namespace
|
|||
|
||||
try
|
||||
{
|
||||
ctx->Setup(opts);
|
||||
_ctx->Setup(opts);
|
||||
}
|
||||
catch (llarp::util::bind_socket_error& ex)
|
||||
{
|
||||
llarp::LogError(fmt::format("{}, is lokinet already running? 🤔", ex.what()));
|
||||
exit_code.set_value(1);
|
||||
startup.set_exception(std::current_exception());
|
||||
return;
|
||||
}
|
||||
catch (std::exception& ex)
|
||||
{
|
||||
llarp::LogError(fmt::format("failed to start up lokinet: {}", ex.what()));
|
||||
exit_code.set_value(1);
|
||||
startup.set_exception(std::current_exception());
|
||||
return;
|
||||
}
|
||||
llarp::util::SetThreadName("llarp-mainloop");
|
||||
|
||||
auto result = ctx->Run(opts);
|
||||
startup.set_value(_ctx);
|
||||
auto result = _ctx->Run(opts);
|
||||
exit_code.set_value(result);
|
||||
}
|
||||
catch (std::exception& e)
|
||||
|
|
|
@ -185,7 +185,7 @@ namespace llarp
|
|||
void
|
||||
Context::SigINT()
|
||||
{
|
||||
if (router)
|
||||
if (router and router->IsRunning())
|
||||
{
|
||||
llarp::log::debug(logcat, "Handling SIGINT");
|
||||
/// async stop router on sigint
|
||||
|
|
Loading…
Reference in a new issue