mirror of
https://github.com/matrix-construct/construct
synced 2024-12-25 15:04:10 +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(SIGUSR1);
|
||||
sigs.add(SIGUSR2);
|
||||
sigs.add(SIGIO);
|
||||
sigs.async_wait(sigfd_handler);
|
||||
|
||||
// Because we registered signal handlers with the io_context, ios->run()
|
||||
|
@ -211,6 +212,7 @@ catch(const std::exception &e)
|
|||
return false;
|
||||
}
|
||||
|
||||
static void handle_io();
|
||||
static void handle_usr2();
|
||||
static void handle_usr1();
|
||||
static void handle_quit();
|
||||
|
@ -240,6 +242,7 @@ sigfd_handler(const boost::system::error_code &ec,
|
|||
|
||||
switch(signum)
|
||||
{
|
||||
case SIGIO: handle_io(); break;
|
||||
case SIGUSR1: handle_usr1(); break;
|
||||
case SIGUSR2: handle_usr2(); break;
|
||||
case SIGINT: handle_interruption(); break;
|
||||
|
@ -288,6 +291,17 @@ catch(const std::exception &e)
|
|||
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
|
||||
handle_hangup()
|
||||
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([iphlpapi.h], [IPHLPAPI_H])
|
||||
|
||||
dnl linux platform
|
||||
RB_CHK_SYSHEADER([aio.h], [AIO_H])
|
||||
|
||||
dnl experimental
|
||||
RB_CHK_SYSHEADER([experimental/string_view], [EXPERIMENTAL_STRING_VIEW])
|
||||
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 Installation Layout
|
||||
|
|
|
@ -45,6 +45,9 @@
|
|||
/// during IOs.
|
||||
namespace ircd::fs
|
||||
{
|
||||
struct aio;
|
||||
struct init;
|
||||
|
||||
IRCD_EXCEPTION(ircd::error, 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 string_view &name, const const_raw_buffer &buf);
|
||||
|
||||
struct init;
|
||||
void notify();
|
||||
}
|
||||
|
||||
struct ircd::fs::init
|
||||
{
|
||||
std::unique_ptr<fs::aio> aio;
|
||||
|
||||
init();
|
||||
~init() noexcept;
|
||||
};
|
||||
|
|
198
ircd/fs.cc
198
ircd/fs.cc
|
@ -26,6 +26,10 @@
|
|||
#include <boost/filesystem.hpp>
|
||||
#include <ircd/asio.h>
|
||||
|
||||
#ifdef IRCD_USE_AIO
|
||||
#include <RB_INC_AIO_H
|
||||
#endif
|
||||
|
||||
namespace ircd::fs
|
||||
{
|
||||
using namespace boost::filesystem;
|
||||
|
@ -54,6 +58,16 @@ ircd::fs::paths
|
|||
{ "db", DBPATH },
|
||||
}};
|
||||
|
||||
ircd::fs::init::init()
|
||||
:aio{std::make_unique<fs::aio>()}
|
||||
{
|
||||
}
|
||||
|
||||
ircd::fs::init::~init()
|
||||
noexcept
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::fs::write(const std::string &path,
|
||||
const const_raw_buffer &buf)
|
||||
|
@ -89,72 +103,6 @@ ircd::fs::append(const std::string &path,
|
|||
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
|
||||
ircd::fs::read(const std::string &path)
|
||||
{
|
||||
|
@ -164,7 +112,6 @@ ircd::fs::read(const std::string &path)
|
|||
std::istream_iterator<char> e{};
|
||||
return std::string{b, e};
|
||||
}
|
||||
#endif
|
||||
|
||||
ircd::string_view
|
||||
ircd::fs::read(const string_view &path,
|
||||
|
@ -336,3 +283,120 @@ catch(const std::out_of_range &e)
|
|||
{
|
||||
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