blob: 09ed5cccc669f592fa7dc5122af61e6b0032734d [file] [log] [blame]
//
// Copyright (C) 2022 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef __IO_URING_CPP_H
#define __IO_URING_CPP_H
#include <errno.h>
#include <string.h>
#include <sys/uio.h>
#include <algorithm>
#include <memory>
#include <optional>
#include <variant>
#include "IoUringCQE.h"
#include "IoUringSQE.h"
namespace io_uring_cpp {
template <typename Err, typename Res>
struct [[nodiscard]] Result : public std::variant<Err, Res> {
constexpr bool IsOk() const { return std::holds_alternative<Res>(*this); }
constexpr bool IsErr() const { return std::holds_alternative<Err>(*this); }
constexpr Err GetError() const { return std::get<Err>(*this); }
constexpr const Res& GetResult() const& { return std::get<Res>(*this); }
constexpr Res&& GetResult() && { return std::get<Res>(*this); }
};
class IoUringInterface {
public:
virtual ~IoUringInterface() {}
// Registration helpers
// Register a fixed set of buffers to kernel.
virtual Errno RegisterBuffers(const struct iovec* iovecs,
size_t iovec_size) = 0;
virtual Errno UnregisterBuffers() = 0;
// Register a set of file descriptors to kernel.
virtual Errno RegisterFiles(const int* files, size_t files_size) = 0;
virtual Errno UnregisterFiles() = 0;
// Append a submission entry into this io_uring. This does not submit the
// operation to the kernel. For that, call |IoUringInterface::Submit()|
virtual IoUringSQE PrepRead(int fd, void *buf, unsigned nbytes,
uint64_t offset) = 0;
// Caller is responsible for making sure the input memory is available until
// this write operation completes.
virtual IoUringSQE PrepWrite(int fd, const void *buf, unsigned nbytes,
uint64_t offset) = 0;
// Return number of SQEs available in the queue. If this is 0, subsequent
// calls to Prep*() functions will fail.
virtual size_t SQELeft() const = 0;
// Return number of SQEs currently in the queue. SQEs already submitted would
// not be counted.
virtual size_t SQEReady() const = 0;
// Ring operations
virtual IoUringSubmitResult Submit() = 0;
// Submit and block until |completions| number of CQEs are available
virtual IoUringSubmitResult SubmitAndWait(size_t completions) = 0;
virtual Result<Errno, IoUringCQE> PopCQE() = 0;
virtual Result<Errno, std::vector<IoUringCQE>> PopCQE(unsigned int count) = 0;
virtual Result<Errno, IoUringCQE> PeekCQE() = 0;
static std::unique_ptr<IoUringInterface> CreateLinuxIoUring(int queue_depth,
int flags);
};
} // namespace io_uring_cpp
#endif