0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-12-27 07:54:05 +01:00

ircd: Improve main control flow for termination condition during init.

This commit is contained in:
Jason Volk 2018-08-28 14:04:43 -07:00
parent 89fbab2d7a
commit a4e4424ede
7 changed files with 137 additions and 25 deletions

View file

@ -36,9 +36,8 @@ struct ircd::db::database::env::state
{ "rdb high", 128_KiB, 0 }, { "rdb high", 128_KiB, 0 },
}}; }};
state(database *const &d) state(database *const &d);
:d{*d} ~state() noexcept;
{}
}; };
struct ircd::db::database::env::state::task struct ircd::db::database::env::state::task

View file

@ -175,6 +175,7 @@ ircd::fs::aio::MAX_EVENTS
// //
ircd::fs::aio::aio() ircd::fs::aio::aio()
try
:resfd :resfd
{ {
*ircd::ios, int(syscall(::eventfd, semval, EFD_NONBLOCK)) *ircd::ios, int(syscall(::eventfd, semval, EFD_NONBLOCK))
@ -182,11 +183,27 @@ ircd::fs::aio::aio()
{ {
syscall<SYS_io_setup>(MAX_EVENTS, &idp); syscall<SYS_io_setup>(MAX_EVENTS, &idp);
set_handle(); set_handle();
log::debug
{
"Established AIO context %p", this
};
}
catch(const std::exception &e)
{
log::error
{
"Error starting AIO context %p :%s",
(const void *)this,
e.what()
};
} }
ircd::fs::aio::~aio() ircd::fs::aio::~aio()
noexcept noexcept try
{ {
const ctx::uninterruptible::nothrow ui;
interrupt(); interrupt();
wait(); wait();
@ -195,6 +212,15 @@ noexcept
syscall<SYS_io_destroy>(idp); syscall<SYS_io_destroy>(idp);
} }
catch(const std::exception &e)
{
log::critical
{
"Error shutting down AIO context %p :%s",
(const void *)this,
e.what()
};
}
bool bool
ircd::fs::aio::interrupt() ircd::fs::aio::interrupt()

View file

@ -951,6 +951,7 @@ noexcept
// Can't join to bare metal, only from within another context. // Can't join to bare metal, only from within another context.
if(current) if(current)
{ {
const uninterruptible::nothrow ui;
interrupt(); interrupt();
join(); join();
return; return;
@ -1019,8 +1020,9 @@ ircd::ctx::pool::pool(const char *const &name,
ircd::ctx::pool::~pool() ircd::ctx::pool::~pool()
noexcept noexcept
{ {
interrupt(); terminate();
join(); join();
assert(ctxs.empty()); assert(ctxs.empty());
assert(queue.empty()); assert(queue.empty());
} }

View file

@ -148,8 +148,16 @@ noexcept
}; };
request.terminate(); request.terminate();
request.join(); log::debug
{
log, "Waiting for %zu active of %zu client request contexts; %zu pending; %zu queued",
request.active(),
request.size(),
request.pending(),
request.queued()
};
request.join();
log::debug log::debug
{ {
log, "All contexts joined; all requests are clear." log, "All contexts joined; all requests are clear."
@ -1014,6 +1022,17 @@ catch(const std::exception &e)
return; return;
} }
catch(...)
{
log::critical
{
log, "'%s': Unknown error closing database(%p)",
name,
this
};
return;
}
void void
ircd::db::database::operator()(const delta &delta) ircd::db::database::operator()(const delta &delta)
@ -1876,7 +1895,30 @@ noexcept
// //
// //
// env // env::state
//
ircd::db::database::env::state::state(database *const &d)
:d{*d}
{
}
ircd::db::database::env::state::~state()
noexcept
{
for(auto &p : pool) try
{
p.terminate();
p.join();
}
catch(...)
{
continue;
}
}
//
// env::env
// //
ircd::db::database::env::env(database *const &d) ircd::db::database::env::env(database *const &d)

View file

@ -24,7 +24,7 @@ namespace ircd
boost::asio::io_context *ios; // user's io service boost::asio::io_context *ios; // user's io service
ctx::ctx *main_context; // Main program loop ctx::ctx *main_context; // Main program loop
void set_runlevel(const enum runlevel &); bool set_runlevel(const enum runlevel &);
void main() noexcept; void main() noexcept;
} }
@ -129,14 +129,45 @@ bool
ircd::quit() ircd::quit()
noexcept noexcept
{ {
if(runlevel != runlevel::RUN) log::debug
return false; {
"IRCd quit requested from runlevel:%s ctx:%p main_context:%p",
reflect(runlevel),
(const void *)ctx::current,
(const void *)main_context
};
if(!main_context) if(main_context) switch(runlevel)
return false; {
case runlevel::READY:
{
ctx::terminate(*main_context);
main_context = nullptr;
ircd::set_runlevel(runlevel::HALT);
return true;
}
ctx::notify(*main_context); case runlevel::START:
return true; {
ctx::terminate(*main_context);
main_context = nullptr;
return true;
}
case runlevel::RUN:
{
ctx::notify(*main_context);
main_context = nullptr;
return true;
}
case runlevel::HALT:
case runlevel::QUIT:
case runlevel::FAULT:
return false;
}
return false;
} }
/// Main context; Main program. Do not call this function directly. /// Main context; Main program. Do not call this function directly.
@ -162,10 +193,6 @@ noexcept try
// threads, but we consider this one thread a main thread for now... // threads, but we consider this one thread a main thread for now...
ircd::thread_id = std::this_thread::get_id(); ircd::thread_id = std::this_thread::get_id();
// When this function is entered IRCd will transition to START indicating
// that subsystems are initializing.
ircd::set_runlevel(runlevel::START);
// When this function completes, subsystems are done shutting down and IRCd // When this function completes, subsystems are done shutting down and IRCd
// transitions to HALT. // transitions to HALT.
const unwind halted{[] const unwind halted{[]
@ -173,6 +200,10 @@ noexcept try
set_runlevel(runlevel::HALT); set_runlevel(runlevel::HALT);
}}; }};
// When this function is entered IRCd will transition to START indicating
// that subsystems are initializing.
ircd::set_runlevel(runlevel::START);
// These objects are the init()'s and fini()'s for each subsystem. // These objects are the init()'s and fini()'s for each subsystem.
// Appearing here ties their life to the main context. Initialization can // Appearing here ties their life to the main context. Initialization can
// also occur in ircd::init() or static initialization itself if either are // also occur in ircd::init() or static initialization itself if either are
@ -247,10 +278,13 @@ ircd::uptime()
/// prevent the callback from continuing execution on some ircd::ctx stack and /// prevent the callback from continuing execution on some ircd::ctx stack and
/// instead invoke their function on the main stack in their own io_context /// instead invoke their function on the main stack in their own io_context
/// event slice. /// event slice.
void bool
ircd::set_runlevel(const enum runlevel &new_runlevel) ircd::set_runlevel(const enum runlevel &new_runlevel)
try try
{ {
if(ircd::runlevel == new_runlevel)
return false;
log::debug log::debug
{ {
"IRCd runlevel transition from '%s' to '%s' (notifying %zu)", "IRCd runlevel transition from '%s' to '%s' (notifying %zu)",
@ -287,6 +321,8 @@ try
ircd::post(call_users); ircd::post(call_users);
else else
call_users(); call_users();
return true;
} }
catch(const std::exception &e) catch(const std::exception &e)
{ {
@ -296,6 +332,7 @@ catch(const std::exception &e)
}; };
ircd::terminate(); ircd::terminate();
return false;
} }
ircd::string_view ircd::string_view

View file

@ -43,6 +43,11 @@ try
origin origin
} }
{ {
const unwind::exceptional uw{[]
{
m::imports.clear();
}};
init_keys(); init_keys();
init_imports(); init_imports();
presence::set(me, "online", me_online_status_msg); presence::set(me, "online", me_online_status_msg);
@ -53,8 +58,6 @@ catch(const m::error &e)
{ {
log, "%s %s", e.what(), e.content log, "%s %s", e.what(), e.content
}; };
m::imports.clear();
} }
catch(const std::exception &e) catch(const std::exception &e)
{ {
@ -62,8 +65,6 @@ catch(const std::exception &e)
{ {
log, "%s", e.what() log, "%s", e.what()
}; };
m::imports.clear();
} }
ircd::m::init::~init() ircd::m::init::~init()
@ -93,7 +94,7 @@ ircd::m::init::init_keys()
try try
{ {
m::imports.emplace("s_keys"s, "s_keys"s); m::imports.emplace("s_keys"s, "s_keys"s);
static m::import<void ()> init_my_keys m::import<void ()> init_my_keys
{ {
"s_keys", "init_my_keys" "s_keys", "init_my_keys"
}; };

View file

@ -32,7 +32,7 @@ namespace ircd::openssl
class... args> class... args>
static int call(function&& f, args&&... a); static int call(function&& f, args&&... a);
static int genprime_cb(const int, const int, BN_GENCB *const); static int genprime_cb(const int, const int, BN_GENCB *const) noexcept;
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -1802,6 +1802,7 @@ int
ircd::openssl::genprime_cb(const int stat, ircd::openssl::genprime_cb(const int stat,
const int ith, const int ith,
BN_GENCB *const ctx) BN_GENCB *const ctx)
noexcept try
{ {
assert(ctx != nullptr); assert(ctx != nullptr);
auto &arg{ctx->arg}; auto &arg{ctx->arg};
@ -1844,6 +1845,10 @@ ircd::openssl::genprime_cb(const int stat,
return false; return false;
} }
} }
catch(...)
{
return false;
}
// //
// call() // call()