mirror of
https://github.com/matrix-construct/construct
synced 2025-01-22 04:20:03 +01:00
ircd::net: Add interface for native_non_blocking(); mitigate unconditional ioctl.
This commit is contained in:
parent
4d2478f814
commit
b07fa8c110
3 changed files with 43 additions and 2 deletions
|
@ -14,8 +14,10 @@
|
||||||
namespace ircd::net
|
namespace ircd::net
|
||||||
{
|
{
|
||||||
struct sock_opts;
|
struct sock_opts;
|
||||||
|
IRCD_OVERLOAD(system);
|
||||||
|
|
||||||
bool v6only(const socket &);
|
bool v6only(const socket &);
|
||||||
|
bool blocking(const socket &, system_t);
|
||||||
bool blocking(const socket &);
|
bool blocking(const socket &);
|
||||||
bool nopush(const socket &);
|
bool nopush(const socket &);
|
||||||
bool nodelay(const socket &);
|
bool nodelay(const socket &);
|
||||||
|
@ -30,6 +32,7 @@ namespace ircd::net
|
||||||
|
|
||||||
// returns true if supported, false if unsupported; failures will throw.
|
// returns true if supported, false if unsupported; failures will throw.
|
||||||
bool v6only(socket &, const bool);
|
bool v6only(socket &, const bool);
|
||||||
|
bool blocking(socket &, const bool, system_t);
|
||||||
bool blocking(socket &, const bool);
|
bool blocking(socket &, const bool);
|
||||||
bool nopush(socket &, const bool);
|
bool nopush(socket &, const bool);
|
||||||
bool nodelay(socket &, const bool);
|
bool nodelay(socket &, const bool);
|
||||||
|
|
37
ircd/net.cc
37
ircd/net.cc
|
@ -1114,8 +1114,11 @@ ircd::net::nopush(socket &socket,
|
||||||
/// Toggles the behavior of non-async asio calls.
|
/// Toggles the behavior of non-async asio calls.
|
||||||
///
|
///
|
||||||
/// This option affects very little in practice and only sets a flag in
|
/// This option affects very little in practice and only sets a flag in
|
||||||
/// userspace in asio, not an actual ioctl(). Specifically:
|
/// userspace in asio, not an actual ioctl(2) (XXX this is not true anymore,
|
||||||
|
/// sd.non_blocking() and sd.native_non_blocking() both seem to ioctl(2)).
|
||||||
|
/// See below the deprecated section.
|
||||||
///
|
///
|
||||||
|
/// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
|
||||||
/// * All sockets are already set by asio to FIONBIO=1 no matter what, thus
|
/// * All sockets are already set by asio to FIONBIO=1 no matter what, thus
|
||||||
/// nothing really blocks the event loop ever by default unless you try hard.
|
/// nothing really blocks the event loop ever by default unless you try hard.
|
||||||
///
|
///
|
||||||
|
@ -1134,13 +1137,35 @@ ircd::net::nopush(socket &socket,
|
||||||
/// in this project there is never a reason to ever set this to true,
|
/// in this project there is never a reason to ever set this to true,
|
||||||
/// however, sockets do get constructed by asio in blocking mode by default
|
/// however, sockets do get constructed by asio in blocking mode by default
|
||||||
/// so we mostly use this function to set it to non-blocking.
|
/// so we mostly use this function to set it to non-blocking.
|
||||||
|
/// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
|
||||||
///
|
///
|
||||||
|
/// The kern argument has been added to decide between native_non_blocking()
|
||||||
|
/// (when kern=true) or non_blocking() (when kern=false). These both set
|
||||||
|
/// different flags in asio but they both result in the same ioctl(FIONBIO)
|
||||||
|
/// probably due to third-party libraries flipping FIONBIO outside of asio's
|
||||||
|
/// knowledge and naive users complaining too much to the maintainer.
|
||||||
|
///
|
||||||
|
/// To deal with this we have added a query to the sd.non_blocking() getter
|
||||||
|
/// which AT LEAST FOR NOW only reads asio's flags without a syscall and
|
||||||
|
/// won't call the sd.non_blocking() setter if it's superfluous.
|
||||||
bool
|
bool
|
||||||
ircd::net::blocking(socket &socket,
|
ircd::net::blocking(socket &socket,
|
||||||
const bool b)
|
const bool b)
|
||||||
{
|
{
|
||||||
ip::tcp::socket &sd(socket);
|
ip::tcp::socket &sd(socket);
|
||||||
sd.non_blocking(!b);
|
if(likely(sd.non_blocking() == b))
|
||||||
|
sd.non_blocking(!b);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ircd::net::blocking(socket &socket,
|
||||||
|
const bool b,
|
||||||
|
system_t)
|
||||||
|
{
|
||||||
|
ip::tcp::socket &sd(socket);
|
||||||
|
sd.native_non_blocking(!b);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1292,6 +1317,14 @@ ircd::net::blocking(const socket &socket)
|
||||||
return !sd.non_blocking();
|
return !sd.non_blocking();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ircd::net::blocking(const socket &socket,
|
||||||
|
system_t)
|
||||||
|
{
|
||||||
|
const ip::tcp::socket &sd(socket);
|
||||||
|
return !sd.native_non_blocking();
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ircd::net::v6only(const socket &socket)
|
ircd::net::v6only(const socket &socket)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1070,8 +1070,13 @@ ircd::net::acceptor::accepted(const std::shared_ptr<socket> &sock)
|
||||||
assert(bool(cb));
|
assert(bool(cb));
|
||||||
assert(bool(sock));
|
assert(bool(sock));
|
||||||
|
|
||||||
|
#if !defined(BSD_BASED_OS)
|
||||||
// Toggles the behavior of non-async functions; see func comment
|
// Toggles the behavior of non-async functions; see func comment
|
||||||
|
// This is not needed on BSD because the socket inherits the listener's
|
||||||
|
// non-blocking disposition.
|
||||||
blocking(*sock, false);
|
blocking(*sock, false);
|
||||||
|
#endif
|
||||||
|
|
||||||
cb(*this, sock);
|
cb(*this, sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue