0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-06-02 18:18:56 +02:00
construct/ircd/aio.h

118 lines
3.1 KiB
C
Raw Normal View History

2018-02-04 03:22:01 +01:00
// Matrix Construct
//
// Copyright (C) Matrix Construct Developers, Authors & Contributors
2018-02-04 03:22:01 +01:00
// Copyright (C) 2016-2018 Jason Volk <jason@zemos.net>
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
2018-02-04 03:22:01 +01:00
// copyright notice and this permission notice is present in all copies. The
// full license for this software is available in the LICENSE file.
#pragma once
#define HAVE_AIO_H
#include <linux/aio_abi.h>
namespace ircd::fs::aio
2018-08-21 07:45:06 +02:00
{
struct request;
void prefetch(const fd &, const size_t &, const read_opts &);
size_t write(const fd &, const const_iovec_view &, const write_opts &);
size_t read(const fd &, const const_iovec_view &, const read_opts &);
void fdsync(const fd &, const sync_opts &);
void fsync(const fd &, const sync_opts &);
2018-08-21 07:45:06 +02:00
}
/// AIO context instance from the kernel. Right now this is a singleton with
/// an extern instance pointer at fs::aio::context maintained by fs::aio::init.
struct ircd::fs::aio::kernel
{
/// Internal semaphore for synchronization of this object
ctx::dock dock;
/// The semaphore value for the eventfd which we keep here.
2018-02-06 07:42:40 +01:00
uint64_t semval {0};
/// An eventfd which will be notified by the kernel; we integrate this with
/// the ircd io_service core epoll() event loop. The EFD_SEMAPHORE flag is
/// not used to reduce the number of triggers. We can collect multiple AIO
2018-02-06 07:42:40 +01:00
/// completions after a single trigger to this fd. Because EFD_SEMAPHORE is
/// not set, the semval which is kept above will reflect a hint for how
/// many AIO's are done.
asio::posix::stream_descriptor resfd;
/// Handler to the io context we submit requests to the kernel with
2018-02-06 07:42:40 +01:00
aio_context_t idp {0};
// Callback stack invoked when the sigfd is notified of completed events.
void handle_event(const io_event &) noexcept;
void handle_events() noexcept;
void handle(const boost::system::error_code &, const size_t) noexcept;
void set_handle();
void submit(request &) noexcept;
// Control panel
2018-08-19 07:58:43 +02:00
bool wait();
bool interrupt();
kernel();
~kernel() noexcept;
};
/// Generic request control block.
struct ircd::fs::aio::request
:iocb
{
struct read;
struct write;
2018-08-19 07:58:43 +02:00
struct fdsync;
struct fsync;
ctx::ctx *waiter {ctx::current};
ssize_t retval {std::numeric_limits<ssize_t>::min()};
ssize_t errcode {0}; union
{
const read_opts *ropts {nullptr};
const write_opts *wopts;
const sync_opts *sopts;
};
public:
const_iovec_view iovec() const;
size_t operator()();
void cancel();
request(const int &fd);
~request() noexcept;
};
/// Read request control block
struct ircd::fs::aio::request::read
:request
{
read(const int &fd, const const_iovec_view &, const read_opts &);
};
/// Write request control block
struct ircd::fs::aio::request::write
:request
{
write(const int &fd, const const_iovec_view &, const write_opts &);
};
2018-08-19 07:58:43 +02:00
/// fdsync request control block
struct ircd::fs::aio::request::fdsync
:request
{
fdsync(const int &fd, const sync_opts &);
2018-08-19 07:58:43 +02:00
};
/// fsync request control block
struct ircd::fs::aio::request::fsync
:request
{
fsync(const int &fd, const sync_opts &);
2018-08-19 07:58:43 +02:00
};