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:
parent
89fbab2d7a
commit
a4e4424ede
7 changed files with 137 additions and 25 deletions
5
include/ircd/db/database/env/state.h
vendored
5
include/ircd/db/database/env/state.h
vendored
|
@ -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
|
||||||
|
|
28
ircd/aio.cc
28
ircd/aio.cc
|
@ -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()
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
46
ircd/db.cc
46
ircd/db.cc
|
@ -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)
|
||||||
|
|
61
ircd/ircd.cc
61
ircd/ircd.cc
|
@ -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
|
||||||
|
|
11
ircd/m/m.cc
11
ircd/m/m.cc
|
@ -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"
|
||||||
};
|
};
|
||||||
|
|
|
@ -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()
|
||||||
|
|
Loading…
Reference in a new issue