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:
parent
47a5136045
commit
c1737e167c
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
31
ircd/ctx.cc
31
ircd/ctx.cc
|
@ -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
|
||||
)
|
||||
}
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
42
ircd/ios.cc
42
ircd/ios.cc
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue