0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-06-07 12:38:56 +02:00

ircd::ios: Employ the asio::executor abstraction w/ backward-compat.

This commit is contained in:
Jason Volk 2020-02-27 10:11:59 -08:00
parent 47a5136045
commit c1737e167c
10 changed files with 104 additions and 58 deletions

View file

@ -296,7 +296,7 @@ noexcept try
// Associates libircd with our io_context and posts the initial routines
// to that io_context. Execution of IRCd will then occur during ios::run()
ircd::init(ios);
ircd::init(ios.get_executor());
// If the user wants to immediately drop to an interactive command line
// without having to send a ctrl-c for it, that is provided here. This does

View file

@ -52,12 +52,21 @@ namespace boost
#pragma GCC visibility pop
///
/// The following IRCd headers are not included in the main stdinc.h list of
/// includes because they require boost directly or symbols which we cannot
/// forward declare. You should include this in your definition file if you
/// need these low-level interfaces.
///
// Boost version dependent behavior for getting the io_service/io_context
// abstract executor (recent versions) or the derived instance (old versions).
namespace ircd::ios
{
#if BOOST_VERSION >= 107000
asio::executor &get() noexcept;
#else
asio::io_context &get() noexcept;
#endif
}
// The following IRCd headers are not included in the main stdinc.h list of
// includes because they require boost directly or symbols which we cannot
// forward declare. You should include this in your definition file if you
// need these low-level interfaces.
// Context system headers depending on boost.
#include <ircd/ctx/continuation.h>
@ -65,4 +74,22 @@ namespace boost
// Network system headers depending on boost.
#include <ircd/net/asio.h>
#if BOOST_VERSION >= 107000
inline boost::asio::executor &
ircd::ios::get()
noexcept
{
assert(bool(main));
return main;
}
#else
inline boost::asio::io_context &
ircd::ios::get()
noexcept
{
auto &context(const_cast<asio::execution_context &>(main.context()));
return static_cast<asio::io_context &>(context);
}
#endif
#endif HAVE_IRCD_ASIO_H

View file

@ -18,6 +18,7 @@
/// Forward declarations for boost::asio because it is not included here.
namespace boost::asio
{
struct executor;
struct io_context;
template<class function>
@ -43,23 +44,21 @@ namespace ircd::ios
struct post;
extern std::thread::id main_thread_id;
extern asio::io_context *user;
extern asio::executor user;
extern asio::executor main;
bool available() noexcept;
bool is_main_thread() noexcept;
void assert_main_thread();
const string_view &name(const descriptor &);
const string_view &name(const handler &);
bool is_main_thread();
void assert_main_thread();
bool available() noexcept;
asio::io_context &get() noexcept;
const uint64_t &epoch() noexcept;
void forked_parent();
void forked_child();
void forking();
void init(asio::io_context &user);
void init(asio::executor &&);
}
namespace ircd
@ -286,6 +285,7 @@ ircd::ios::assert_main_thread()
inline bool
__attribute__((always_inline))
ircd::ios::is_main_thread()
noexcept
{
return std::this_thread::get_id() == main_thread_id ||
main_thread_id == std::thread::id();

View file

@ -116,9 +116,9 @@ namespace ircd
seconds uptime();
// Control panel
void init(boost::asio::io_context &ios);
void cont() noexcept;
bool quit() noexcept;
void init(boost::asio::executor &&);
}
#endif // HAVE_IRCD_IRCD_H

View file

@ -112,8 +112,7 @@ struct ircd::net::socket
void connect(const endpoint &, const open_opts &, eptr_handler);
bool cancel() noexcept;
socket(asio::ssl::context & = sslv23_client,
boost::asio::io_service & = ios::get());
socket(asio::ssl::context & = sslv23_client);
// Socket cannot be copied or moved; must be constructed as shared ptr
socket(socket &&) = delete;

View file

@ -59,13 +59,27 @@ ircd::ctx::ctx::ios_desc
/// Internal context struct ctor
ircd::ctx::ctx::ctx(const string_view &name,
const size_t &stack_max,
const context::flags &flags,
boost::asio::io_service &ios)
:name{name}
,flags{flags}
,strand{ios}
,alarm{ios}
,stack{stack_max}
const context::flags &flags)
:name
{
name
}
,flags
{
flags
}
,strand
{
ios::get()
}
,alarm
{
ios::get()
}
,stack
{
stack_max
}
{
}
@ -1223,8 +1237,7 @@ ircd::ctx::context::context(const string_view &name,
(
name,
stack_sz,
!current? flags | POST : flags,
ios::get()
!current? flags | POST : flags
)
}
{

View file

@ -55,7 +55,7 @@ struct ircd::ctx::ctx
int8_t nice {0}; // Scheduling priority nice-value
int8_t ionice {0}; // IO priority nice-value (defaults for fs::opts)
int32_t notes {0}; // norm: 0 = asleep; 1 = awake; inc by others; dec by self
boost::asio::io_service::strand strand; // mutex/serializer
boost::asio::io_context::strand strand; // mutex/serializer
boost::asio::deadline_timer alarm; // acting semaphore (64B)
boost::asio::yield_context *yc {nullptr}; // boost interface
continuation *cont {nullptr}; // valid when asleep; invalid when awake
@ -80,10 +80,9 @@ struct ircd::ctx::ctx
void operator()(boost::asio::yield_context, const std::function<void ()>) noexcept;
void spawn(context::function func);
ctx(const string_view &name = "<noname>"_sv,
const size_t &stack_max = DEFAULT_STACK_SIZE,
const context::flags &flags = (context::flags)0U,
boost::asio::io_service &ios = ircd::ios::get());
ctx(const string_view &name = "<noname>"_sv,
const size_t &stack_max = DEFAULT_STACK_SIZE,
const context::flags & = (context::flags)0U);
ctx(ctx &&) = delete;
ctx(const ctx &) = delete;

View file

@ -12,9 +12,14 @@
decltype(ircd::ios::main_thread_id)
ircd::ios::main_thread_id;
/// The embedder/executable's (library user) asio::executor provided on init.
decltype(ircd::ios::user)
ircd::ios::user;
/// Our library-specific/isolate executor.
decltype(ircd::ios::main)
ircd::ios::main;
decltype(ircd::boost_version_api)
ircd::boost_version_api
{
@ -37,7 +42,7 @@ ircd::boost_version_abi
//
void
ircd::ios::init(asio::io_context &user)
ircd::ios::init(asio::executor &&user)
{
// Sample the ID of this thread. Since this is the first transfer of
// control to libircd after static initialization we have nothing to
@ -47,7 +52,10 @@ ircd::ios::init(asio::io_context &user)
main_thread_id = std::this_thread::get_id();
// Set a reference to the user's ios_service
ios::user = &user;
ios::user = std::move(user);
// (simple passthru for now)
ios::main = ios::user;
}
//
@ -306,19 +314,31 @@ namespace ircd::ios
void
ircd::ios::forking()
{
get().notify_fork(asio::execution_context::fork_prepare);
#if BOOST_VERSION >= 107000
get().context().notify_fork(asio::execution_context::fork_prepare);
#else
get().notify_fork(asio::execution_context::fork_prepare);
#endif
}
void
ircd::ios::forked_child()
{
get().notify_fork(asio::execution_context::fork_child);
#if BOOST_VERSION >= 107000
get().context().notify_fork(asio::execution_context::fork_child);
#else
get().notify_fork(asio::execution_context::fork_child);
#endif
}
void
ircd::ios::forked_parent()
{
get().notify_fork(asio::execution_context::fork_parent);
#if BOOST_VERSION >= 107000
get().context().notify_fork(asio::execution_context::fork_parent);
#else
get().notify_fork(asio::execution_context::fork_parent);
#endif
}
//
@ -522,19 +542,9 @@ ircd::ios::post::post(descriptor &descriptor,
boost::asio::post(get(), handle(descriptor, std::move(function)));
}
[[gnu::hot]]
boost::asio::io_context &
ircd::ios::get()
noexcept
{
assert(user);
return *user;
}
[[gnu::hot]]
bool
ircd::ios::available()
noexcept
{
return bool(user);
return bool(main);
}

View file

@ -102,16 +102,15 @@ decltype(ircd::main_context)
ircd::main_context;
/// Sets up the IRCd and its main context, then returns without blocking.
//
/// Pass your io_context instance, it will share it with the rest of your program.
/// An exception will be thrown on error.
///
/// Pass the executor obtained from your io_context instance.
///
/// This function will setup the main program loop of libircd. The execution will
/// occur when your io_context.run() or poll() is further invoked.
///
/// init() can only be called from a run::level::HALT state
void
ircd::init(boost::asio::io_context &user_ios)
ircd::init(boost::asio::executor &&executor)
try
{
// This function must only be called from a HALT state.
@ -122,7 +121,7 @@ try
};
// Setup the core event loop system starting with the user's supplied ios.
ios::init(user_ios);
ios::init(std::move(executor));
// The log is available. but it is console-only until conf opens files.
log::init();

View file

@ -2692,11 +2692,10 @@ ircd::net::socket::total_calls_out
// socket
//
ircd::net::socket::socket(asio::ssl::context &ssl,
boost::asio::io_service &ios)
ircd::net::socket::socket(asio::ssl::context &ssl)
:sd
{
ios
ios::get()
}
,ssl
{
@ -2704,7 +2703,7 @@ ircd::net::socket::socket(asio::ssl::context &ssl,
}
,timer
{
ios
ios::get()
}
{
++instances;