mirror of
https://github.com/matrix-construct/construct
synced 2024-12-26 07:23:53 +01:00
ircd: Preliminary AIO experimental stub on linux platforms.
This commit is contained in:
parent
78c2af094e
commit
6a552e349e
4 changed files with 164 additions and 68 deletions
|
@ -121,6 +121,7 @@ try
|
||||||
sigs.add(SIGTERM);
|
sigs.add(SIGTERM);
|
||||||
sigs.add(SIGUSR1);
|
sigs.add(SIGUSR1);
|
||||||
sigs.add(SIGUSR2);
|
sigs.add(SIGUSR2);
|
||||||
|
sigs.add(SIGIO);
|
||||||
sigs.async_wait(sigfd_handler);
|
sigs.async_wait(sigfd_handler);
|
||||||
|
|
||||||
// Because we registered signal handlers with the io_context, ios->run()
|
// Because we registered signal handlers with the io_context, ios->run()
|
||||||
|
@ -211,6 +212,7 @@ catch(const std::exception &e)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void handle_io();
|
||||||
static void handle_usr2();
|
static void handle_usr2();
|
||||||
static void handle_usr1();
|
static void handle_usr1();
|
||||||
static void handle_quit();
|
static void handle_quit();
|
||||||
|
@ -240,6 +242,7 @@ sigfd_handler(const boost::system::error_code &ec,
|
||||||
|
|
||||||
switch(signum)
|
switch(signum)
|
||||||
{
|
{
|
||||||
|
case SIGIO: handle_io(); break;
|
||||||
case SIGUSR1: handle_usr1(); break;
|
case SIGUSR1: handle_usr1(); break;
|
||||||
case SIGUSR2: handle_usr2(); break;
|
case SIGUSR2: handle_usr2(); break;
|
||||||
case SIGINT: handle_interruption(); break;
|
case SIGINT: handle_interruption(); break;
|
||||||
|
@ -288,6 +291,17 @@ catch(const std::exception &e)
|
||||||
ircd::log::error("SIGUSR2 handler: %s", e.what());
|
ircd::log::error("SIGUSR2 handler: %s", e.what());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
handle_io()
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ircd::fs::notify();
|
||||||
|
}
|
||||||
|
catch(const std::exception &e)
|
||||||
|
{
|
||||||
|
ircd::log::error("SIGIO handler: %s", e.what());
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
handle_hangup()
|
handle_hangup()
|
||||||
try
|
try
|
||||||
|
|
13
configure.ac
13
configure.ac
|
@ -438,6 +438,9 @@ RB_CHK_SYSHEADER([winsock2.h], [WINSOCK2_H])
|
||||||
RB_CHK_SYSHEADER([ws2tcpip.h], [WS2TCPIP_H])
|
RB_CHK_SYSHEADER([ws2tcpip.h], [WS2TCPIP_H])
|
||||||
RB_CHK_SYSHEADER([iphlpapi.h], [IPHLPAPI_H])
|
RB_CHK_SYSHEADER([iphlpapi.h], [IPHLPAPI_H])
|
||||||
|
|
||||||
|
dnl linux platform
|
||||||
|
RB_CHK_SYSHEADER([aio.h], [AIO_H])
|
||||||
|
|
||||||
dnl experimental
|
dnl experimental
|
||||||
RB_CHK_SYSHEADER([experimental/string_view], [EXPERIMENTAL_STRING_VIEW])
|
RB_CHK_SYSHEADER([experimental/string_view], [EXPERIMENTAL_STRING_VIEW])
|
||||||
RB_CHK_SYSHEADER([experimental/optional], [EXPERIMENTAL_OPTIONAL])
|
RB_CHK_SYSHEADER([experimental/optional], [EXPERIMENTAL_OPTIONAL])
|
||||||
|
@ -499,6 +502,16 @@ AM_COND_IF(INTERIX,
|
||||||
],[])
|
],[])
|
||||||
|
|
||||||
|
|
||||||
|
AM_COND_IF(LINUX,
|
||||||
|
[
|
||||||
|
AC_ARG_ENABLE(aio,
|
||||||
|
AC_HELP_STRING([--enable-aio], [Enable AIO support on Linux platforms]),
|
||||||
|
[
|
||||||
|
IRCD_DEFINE(USE_AIO, [1], [Define to 1 if you want AIO support on linux])
|
||||||
|
LIBS="$LIBS -rt"
|
||||||
|
],[])
|
||||||
|
],[])
|
||||||
|
|
||||||
|
|
||||||
dnl ***************************************************************************
|
dnl ***************************************************************************
|
||||||
dnl Installation Layout
|
dnl Installation Layout
|
||||||
|
|
|
@ -45,6 +45,9 @@
|
||||||
/// during IOs.
|
/// during IOs.
|
||||||
namespace ircd::fs
|
namespace ircd::fs
|
||||||
{
|
{
|
||||||
|
struct aio;
|
||||||
|
struct init;
|
||||||
|
|
||||||
IRCD_EXCEPTION(ircd::error, error)
|
IRCD_EXCEPTION(ircd::error, error)
|
||||||
IRCD_EXCEPTION(error, filesystem_error)
|
IRCD_EXCEPTION(error, filesystem_error)
|
||||||
|
|
||||||
|
@ -101,11 +104,13 @@ namespace ircd::fs
|
||||||
bool overwrite(const std::string &name, const const_raw_buffer &buf);
|
bool overwrite(const std::string &name, const const_raw_buffer &buf);
|
||||||
bool overwrite(const string_view &name, const const_raw_buffer &buf);
|
bool overwrite(const string_view &name, const const_raw_buffer &buf);
|
||||||
|
|
||||||
struct init;
|
void notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ircd::fs::init
|
struct ircd::fs::init
|
||||||
{
|
{
|
||||||
|
std::unique_ptr<fs::aio> aio;
|
||||||
|
|
||||||
init();
|
init();
|
||||||
~init() noexcept;
|
~init() noexcept;
|
||||||
};
|
};
|
||||||
|
|
198
ircd/fs.cc
198
ircd/fs.cc
|
@ -26,6 +26,10 @@
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
#include <ircd/asio.h>
|
#include <ircd/asio.h>
|
||||||
|
|
||||||
|
#ifdef IRCD_USE_AIO
|
||||||
|
#include <RB_INC_AIO_H
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace ircd::fs
|
namespace ircd::fs
|
||||||
{
|
{
|
||||||
using namespace boost::filesystem;
|
using namespace boost::filesystem;
|
||||||
|
@ -54,6 +58,16 @@ ircd::fs::paths
|
||||||
{ "db", DBPATH },
|
{ "db", DBPATH },
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
ircd::fs::init::init()
|
||||||
|
:aio{std::make_unique<fs::aio>()}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ircd::fs::init::~init()
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ircd::fs::write(const std::string &path,
|
ircd::fs::write(const std::string &path,
|
||||||
const const_raw_buffer &buf)
|
const const_raw_buffer &buf)
|
||||||
|
@ -89,72 +103,6 @@ ircd::fs::append(const std::string &path,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ircd::fs::init::init()
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
struct aioinit aio {0};
|
|
||||||
aio.aio_threads = 0;
|
|
||||||
aio.aio_num = 64;
|
|
||||||
aio.aio_idle_time = 0;
|
|
||||||
aio_init(&aio);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
ircd::fs::init::~init()
|
|
||||||
noexcept
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0 //_WIN32
|
|
||||||
namespace ircd::fs
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reads the file at path into a string; yields your ircd::ctx.
|
|
||||||
///
|
|
||||||
std::string
|
|
||||||
ircd::fs::read(const std::string &path)
|
|
||||||
{
|
|
||||||
const int fd
|
|
||||||
{
|
|
||||||
syscall(::open, path.c_str(), O_CLOEXEC, O_RDONLY)
|
|
||||||
};
|
|
||||||
|
|
||||||
const unwind close{[&fd]
|
|
||||||
{
|
|
||||||
syscall(::close, fd);
|
|
||||||
}};
|
|
||||||
|
|
||||||
struct stat stat;
|
|
||||||
syscall(::fstat, fd, &stat);
|
|
||||||
const auto &size{stat.st_size};
|
|
||||||
|
|
||||||
std::string ret(size, char{});
|
|
||||||
const mutable_buffer buf
|
|
||||||
{
|
|
||||||
const_cast<char *>(ret.data()), ret.size()
|
|
||||||
};
|
|
||||||
|
|
||||||
struct aiocb cb
|
|
||||||
{
|
|
||||||
fd, 0, data(buf), size(buf), 0
|
|
||||||
};
|
|
||||||
|
|
||||||
syscall(::aio_read, &cb);
|
|
||||||
|
|
||||||
struct aiocb cbs[]
|
|
||||||
{
|
|
||||||
&cb
|
|
||||||
};
|
|
||||||
|
|
||||||
syscall(::aio_suspend, &cbs, sizeof(cbs) / sizeof(aiocb), nullptr);
|
|
||||||
|
|
||||||
ret.resize(read);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
std::string
|
std::string
|
||||||
ircd::fs::read(const std::string &path)
|
ircd::fs::read(const std::string &path)
|
||||||
{
|
{
|
||||||
|
@ -164,7 +112,6 @@ ircd::fs::read(const std::string &path)
|
||||||
std::istream_iterator<char> e{};
|
std::istream_iterator<char> e{};
|
||||||
return std::string{b, e};
|
return std::string{b, e};
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
ircd::string_view
|
ircd::string_view
|
||||||
ircd::fs::read(const string_view &path,
|
ircd::fs::read(const string_view &path,
|
||||||
|
@ -336,3 +283,120 @@ catch(const std::out_of_range &e)
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// linux aio
|
||||||
|
//
|
||||||
|
|
||||||
|
namespace ircd::fs
|
||||||
|
{
|
||||||
|
ctx::ctx *waiter;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ircd::fs::notify()
|
||||||
|
{
|
||||||
|
if(waiter)
|
||||||
|
notify(*waiter);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef IRCD_USE_AIO
|
||||||
|
|
||||||
|
struct ircd::fs::aio
|
||||||
|
{
|
||||||
|
aio() {}
|
||||||
|
~aio() noexcept {}
|
||||||
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
struct ircd::fs::aio
|
||||||
|
{
|
||||||
|
aioinit init {0};
|
||||||
|
|
||||||
|
std::string read(const std::string &path);
|
||||||
|
|
||||||
|
aio();
|
||||||
|
~aio() noexcept;
|
||||||
|
};
|
||||||
|
|
||||||
|
ircd::fs::aio::aio()
|
||||||
|
{
|
||||||
|
init.aio_threads = 0;
|
||||||
|
init.aio_num = 64;
|
||||||
|
init.aio_idle_time = 0;
|
||||||
|
aio_init(&init);
|
||||||
|
|
||||||
|
auto test{[this]
|
||||||
|
{
|
||||||
|
const auto got{this->read("/etc/passwd")};
|
||||||
|
std::cout << "got: " << got << std::endl;
|
||||||
|
}};
|
||||||
|
|
||||||
|
ircd::context
|
||||||
|
{
|
||||||
|
"aiotest", context::POST | context::DETACH, test
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
ircd::fs::aio::~aio()
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reads the file at path into a string; yields your ircd::ctx.
|
||||||
|
///
|
||||||
|
std::string
|
||||||
|
ircd::fs::aio::read(const std::string &path)
|
||||||
|
{
|
||||||
|
const auto fd
|
||||||
|
{
|
||||||
|
syscall(::open, path.c_str(), O_CLOEXEC, O_RDONLY)
|
||||||
|
};
|
||||||
|
|
||||||
|
const unwind close{[&fd]
|
||||||
|
{
|
||||||
|
syscall(::close, fd);
|
||||||
|
}};
|
||||||
|
|
||||||
|
struct stat stat;
|
||||||
|
syscall(::fstat, fd, &stat);
|
||||||
|
const auto &size{stat.st_size};
|
||||||
|
|
||||||
|
std::string ret(size, char{});
|
||||||
|
const mutable_buffer buf
|
||||||
|
{
|
||||||
|
const_cast<char *>(ret.data()), ret.size()
|
||||||
|
};
|
||||||
|
|
||||||
|
struct aiocb cb {0};
|
||||||
|
cb.aio_fildes = fd;
|
||||||
|
cb.aio_offset = 0;
|
||||||
|
cb.aio_buf = buffer::data(buf);
|
||||||
|
cb.aio_nbytes = buffer::size(buf);
|
||||||
|
cb.aio_reqprio = 0;
|
||||||
|
cb.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
|
||||||
|
cb.aio_sigevent.sigev_signo = SIGIO;
|
||||||
|
cb.aio_sigevent.sigev_value.sival_ptr = nullptr;
|
||||||
|
|
||||||
|
syscall(::aio_read, &cb);
|
||||||
|
|
||||||
|
waiter = ctx::current;
|
||||||
|
int errval; do
|
||||||
|
{
|
||||||
|
ctx::wait();
|
||||||
|
}
|
||||||
|
while((errval = ::aio_error(&cb)) == EINPROGRESS);
|
||||||
|
|
||||||
|
const ssize_t bytes
|
||||||
|
{
|
||||||
|
syscall(::aio_return, &cb)
|
||||||
|
};
|
||||||
|
|
||||||
|
assert(bytes >= 0);
|
||||||
|
ret.resize(size_t(bytes));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue