2018-02-04 03:22:01 +01:00
|
|
|
// Matrix Construct
|
|
|
|
//
|
2018-01-11 06:30:31 +01:00
|
|
|
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
2018-02-04 03:22:01 +01:00
|
|
|
// Copyright (C) 2016-2018 Jason Volk <jason@zemos.net>
|
2018-01-11 06:30:31 +01:00
|
|
|
//
|
|
|
|
// 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.
|
2018-01-11 06:30:31 +01:00
|
|
|
|
|
|
|
#pragma once
|
|
|
|
#define HAVE_AIO_H
|
|
|
|
|
|
|
|
#include <linux/aio_abi.h>
|
2018-02-06 07:42:40 +01:00
|
|
|
#include <ircd/asio.h>
|
2018-01-11 06:30:31 +01:00
|
|
|
|
|
|
|
/// AIO context instance. Right now this is a singleton with an extern
|
|
|
|
/// instance at fs::aioctx.
|
|
|
|
struct ircd::fs::aio
|
|
|
|
{
|
|
|
|
struct request;
|
|
|
|
|
|
|
|
/// Maximum number of events we can submit to kernel
|
2018-08-19 07:58:43 +02:00
|
|
|
static constexpr const size_t &MAX_EVENTS {512};
|
2018-01-11 06:30:31 +01:00
|
|
|
|
2018-03-13 00:26:55 +01:00
|
|
|
/// Internal semaphore for synchronization of this object
|
|
|
|
ctx::dock dock;
|
|
|
|
|
2018-01-11 06:30:31 +01:00
|
|
|
/// The semaphore value for the eventfd which we keep here.
|
2018-02-06 07:42:40 +01:00
|
|
|
uint64_t semval {0};
|
2018-01-11 06:30:31 +01:00
|
|
|
|
|
|
|
/// 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;
|
2018-01-11 06:30:31 +01:00
|
|
|
|
|
|
|
/// 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};
|
2018-01-11 06:30:31 +01:00
|
|
|
|
|
|
|
// Callback stack invoked when the sigfd is notified of completed events.
|
|
|
|
void handle_event(const io_event &) noexcept;
|
|
|
|
void handle_events() noexcept;
|
2018-03-08 18:27:32 +01:00
|
|
|
void handle(const boost::system::error_code &, const size_t) noexcept;
|
2018-01-11 06:30:31 +01:00
|
|
|
void set_handle();
|
|
|
|
|
2018-08-19 07:58:43 +02:00
|
|
|
bool wait();
|
2018-03-13 00:26:55 +01:00
|
|
|
bool interrupt();
|
|
|
|
|
2018-02-06 07:42:40 +01:00
|
|
|
aio();
|
|
|
|
~aio() noexcept;
|
2018-01-11 06:30:31 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
/// 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;
|
2018-01-11 06:30:31 +01:00
|
|
|
|
2018-08-16 16:16:13 +02:00
|
|
|
ssize_t retval {std::numeric_limits<ssize_t>::min()};
|
2018-01-11 06:30:31 +01:00
|
|
|
ssize_t errcode {0};
|
2018-01-18 07:03:07 +01:00
|
|
|
ctx::ctx *waiter {ctx::current};
|
2018-01-11 06:30:31 +01:00
|
|
|
|
|
|
|
public:
|
2018-01-18 07:03:07 +01:00
|
|
|
size_t operator()();
|
2018-01-11 06:30:31 +01:00
|
|
|
void cancel();
|
|
|
|
|
|
|
|
request(const int &fd);
|
2018-01-18 07:03:07 +01:00
|
|
|
~request() noexcept;
|
2018-01-11 06:30:31 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
namespace ircd::fs
|
|
|
|
{
|
2018-08-19 08:08:55 +02:00
|
|
|
void prefetch__aio(const fd &, const size_t &, const read_opts &);
|
2018-05-30 11:24:35 +02:00
|
|
|
const_buffer write__aio(const fd &, const const_buffer &, const write_opts &);
|
2018-05-30 11:13:06 +02:00
|
|
|
const_buffer read__aio(const fd &, const mutable_buffer &, const read_opts &);
|
2018-08-19 07:58:43 +02:00
|
|
|
void fdsync__aio(const fd &, const fsync_opts &);
|
|
|
|
void fsync__aio(const fd &, const fsync_opts &);
|
2018-01-11 06:30:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Read request control block
|
|
|
|
struct ircd::fs::aio::request::read
|
|
|
|
:request
|
|
|
|
{
|
2018-02-06 07:42:40 +01:00
|
|
|
read(const int &fd, const mutable_buffer &, const read_opts &);
|
2018-01-11 06:30:31 +01:00
|
|
|
};
|
2018-02-06 08:28:33 +01:00
|
|
|
|
|
|
|
/// Write request control block
|
|
|
|
struct ircd::fs::aio::request::write
|
|
|
|
:request
|
|
|
|
{
|
|
|
|
write(const int &fd, const const_buffer &, 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 fsync_opts &);
|
|
|
|
};
|
|
|
|
|
|
|
|
/// fsync request control block
|
|
|
|
struct ircd::fs::aio::request::fsync
|
|
|
|
:request
|
|
|
|
{
|
|
|
|
fsync(const int &fd, const fsync_opts &);
|
|
|
|
};
|