io/uring: basic Linux io_uring support
This commit is contained in:
parent
935e622915
commit
62d0ceabcc
|
@ -334,6 +334,7 @@ endif
|
|||
subdir('src/util')
|
||||
subdir('src/time')
|
||||
subdir('src/io')
|
||||
subdir('src/io/uring')
|
||||
subdir('src/system')
|
||||
subdir('src/thread')
|
||||
subdir('src/net')
|
||||
|
|
|
@ -4,6 +4,7 @@ option('test', type: 'boolean', value: false, description: 'Build the unit tests
|
|||
|
||||
option('syslog', type: 'feature', description: 'syslog support')
|
||||
option('inotify', type: 'boolean', value: true, description: 'inotify support (for automatic database update)')
|
||||
option('io_uring', type: 'feature', description: 'Linux io_uring support using liburing')
|
||||
|
||||
option('daemon', type: 'boolean', value: true, description: 'enable daemonization')
|
||||
option('systemd', type: 'feature', description: 'systemd support')
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright 2020 CM4all GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* author: Max Kellermann <mk@cm4all.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Operation.hxx"
|
||||
|
||||
#include <boost/intrusive/list_hook.hpp>
|
||||
|
||||
#include <cassert>
|
||||
#include <utility>
|
||||
|
||||
namespace Uring {
|
||||
|
||||
class CancellableOperation
|
||||
: public boost::intrusive::list_base_hook<boost::intrusive::link_mode<boost::intrusive::normal_link>>
|
||||
{
|
||||
Operation *operation;
|
||||
|
||||
public:
|
||||
CancellableOperation(Operation &_operation) noexcept
|
||||
:operation(&_operation)
|
||||
{
|
||||
assert(operation->cancellable == nullptr);
|
||||
operation->cancellable = this;
|
||||
}
|
||||
|
||||
~CancellableOperation() noexcept {
|
||||
assert(operation == nullptr);
|
||||
}
|
||||
|
||||
void Cancel(Operation &_operation) noexcept {
|
||||
(void)_operation;
|
||||
assert(operation == &_operation);
|
||||
|
||||
operation = nullptr;
|
||||
|
||||
// TODO: io_uring_prep_cancel()
|
||||
}
|
||||
|
||||
void OnUringCompletion(int res) noexcept {
|
||||
if (operation == nullptr)
|
||||
return;
|
||||
|
||||
assert(operation->cancellable == this);
|
||||
operation->cancellable = nullptr;
|
||||
|
||||
std::exchange(operation, nullptr)->OnUringCompletion(res);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Uring
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright 2020 CM4all GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* author: Max Kellermann <mk@cm4all.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <exception>
|
||||
|
||||
struct statx;
|
||||
class UniqueFileDescriptor;
|
||||
|
||||
namespace Uring {
|
||||
|
||||
class OpenStatHandler {
|
||||
public:
|
||||
virtual void OnOpenStat(UniqueFileDescriptor fd,
|
||||
struct statx &st) noexcept = 0;
|
||||
virtual void OnOpenStatError(std::exception_ptr e) noexcept = 0;
|
||||
};
|
||||
|
||||
} // namespace Uring
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright 2020 CM4all GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* author: Max Kellermann <mk@cm4all.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "Operation.hxx"
|
||||
#include "CancellableOperation.hxx"
|
||||
|
||||
namespace Uring {
|
||||
|
||||
void
|
||||
Operation::CancelUring() noexcept
|
||||
{
|
||||
if (cancellable == nullptr)
|
||||
return;
|
||||
|
||||
std::exchange(cancellable, nullptr)->Cancel(*this);
|
||||
}
|
||||
|
||||
} // namespace Uring
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright 2020 CM4all GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* author: Max Kellermann <mk@cm4all.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace Uring {
|
||||
|
||||
class CancellableOperation;
|
||||
|
||||
class Operation {
|
||||
friend class CancellableOperation;
|
||||
|
||||
CancellableOperation *cancellable = nullptr;
|
||||
|
||||
public:
|
||||
~Operation() noexcept {
|
||||
CancelUring();
|
||||
}
|
||||
|
||||
bool IsUringPending() const noexcept {
|
||||
return cancellable != nullptr;
|
||||
}
|
||||
|
||||
void CancelUring() noexcept;
|
||||
|
||||
virtual void OnUringCompletion(int res) noexcept = 0;
|
||||
};
|
||||
|
||||
} // namespace Uring
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* Copyright 2020 CM4all GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* author: Max Kellermann <mk@cm4all.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "Queue.hxx"
|
||||
#include "CancellableOperation.hxx"
|
||||
#include "Operation.hxx"
|
||||
#include "util/DeleteDisposer.hxx"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace Uring {
|
||||
|
||||
Queue::Queue(unsigned entries, unsigned flags)
|
||||
:ring(entries, flags)
|
||||
{
|
||||
}
|
||||
|
||||
Queue::~Queue() noexcept
|
||||
{
|
||||
operations.clear_and_dispose(DeleteDisposer{});
|
||||
}
|
||||
|
||||
void
|
||||
Queue::AddPending(struct io_uring_sqe &sqe,
|
||||
Operation &operation) noexcept
|
||||
{
|
||||
auto *c = new CancellableOperation(operation);
|
||||
operations.push_back(*c);
|
||||
io_uring_sqe_set_data(&sqe, c);
|
||||
}
|
||||
|
||||
void
|
||||
Queue::DispatchOneCompletion(struct io_uring_cqe &cqe) noexcept
|
||||
{
|
||||
void *data = io_uring_cqe_get_data(&cqe);
|
||||
if (data != nullptr) {
|
||||
auto *c = (CancellableOperation *)data;
|
||||
c->OnUringCompletion(cqe.res);
|
||||
operations.erase_and_dispose(operations.iterator_to(*c),
|
||||
DeleteDisposer{});
|
||||
}
|
||||
|
||||
ring.SeenCompletion(cqe);
|
||||
}
|
||||
|
||||
bool
|
||||
Queue::DispatchOneCompletion()
|
||||
{
|
||||
auto *cqe = ring.PeekCompletion();
|
||||
if (cqe == nullptr)
|
||||
return false;
|
||||
|
||||
DispatchOneCompletion(*cqe);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
Queue::WaitDispatchOneCompletion()
|
||||
{
|
||||
auto *cqe = ring.WaitCompletion();
|
||||
if (cqe == nullptr)
|
||||
return false;
|
||||
|
||||
DispatchOneCompletion(*cqe);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Uring
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* Copyright 2020 CM4all GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* author: Max Kellermann <mk@cm4all.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Ring.hxx"
|
||||
|
||||
#include <liburing.h>
|
||||
|
||||
#include <boost/intrusive/list.hpp>
|
||||
|
||||
namespace Uring {
|
||||
|
||||
class Operation;
|
||||
class CancellableOperation;
|
||||
|
||||
/**
|
||||
* High-level C++ wrapper for a `struct io_uring`. It supports a
|
||||
* handler class, cancellation, ...
|
||||
*/
|
||||
class Queue {
|
||||
Ring ring;
|
||||
|
||||
boost::intrusive::list<CancellableOperation,
|
||||
boost::intrusive::base_hook<boost::intrusive::list_base_hook<boost::intrusive::link_mode<boost::intrusive::normal_link>>>,
|
||||
boost::intrusive::constant_time_size<false>> operations;
|
||||
|
||||
public:
|
||||
Queue(unsigned entries, unsigned flags);
|
||||
~Queue() noexcept;
|
||||
|
||||
FileDescriptor GetFileDescriptor() const noexcept {
|
||||
return ring.GetFileDescriptor();
|
||||
}
|
||||
|
||||
struct io_uring_sqe *GetSubmitEntry() noexcept {
|
||||
return ring.GetSubmitEntry();
|
||||
}
|
||||
|
||||
bool HasPending() const noexcept {
|
||||
return !operations.empty();
|
||||
}
|
||||
|
||||
protected:
|
||||
void AddPending(struct io_uring_sqe &sqe,
|
||||
Operation &operation) noexcept;
|
||||
|
||||
public:
|
||||
virtual void Push(struct io_uring_sqe &sqe,
|
||||
Operation &operation) noexcept {
|
||||
AddPending(sqe, operation);
|
||||
Submit();
|
||||
}
|
||||
|
||||
void Submit() {
|
||||
ring.Submit();
|
||||
}
|
||||
|
||||
bool DispatchOneCompletion();
|
||||
|
||||
void DispatchCompletions() {
|
||||
while (DispatchOneCompletion()) {}
|
||||
}
|
||||
|
||||
bool WaitDispatchOneCompletion();
|
||||
|
||||
void WaitDispatchCompletions() {
|
||||
while (WaitDispatchOneCompletion()) {}
|
||||
}
|
||||
|
||||
private:
|
||||
void DispatchOneCompletion(struct io_uring_cqe &cqe) noexcept;
|
||||
};
|
||||
|
||||
} // namespace Uring
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Copyright 2020 CM4all GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* author: Max Kellermann <mk@cm4all.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "Ring.hxx"
|
||||
#include "system/Error.hxx"
|
||||
|
||||
namespace Uring {
|
||||
|
||||
Ring::Ring(unsigned entries, unsigned flags)
|
||||
{
|
||||
int error = io_uring_queue_init(entries, &ring, flags);
|
||||
if (error < 0)
|
||||
throw MakeErrno(-error, "io_uring_queue_init() failed");
|
||||
}
|
||||
|
||||
void
|
||||
Ring::Submit()
|
||||
{
|
||||
int error = io_uring_submit(&ring);
|
||||
if (error < 0)
|
||||
throw MakeErrno(-error, "io_uring_submit() failed");
|
||||
}
|
||||
|
||||
struct io_uring_cqe *
|
||||
Ring::WaitCompletion()
|
||||
{
|
||||
struct io_uring_cqe *cqe;
|
||||
int error = io_uring_wait_cqe(&ring, &cqe);
|
||||
if (error < 0) {
|
||||
if (error == -EAGAIN)
|
||||
return nullptr;
|
||||
|
||||
throw MakeErrno(-error, "io_uring_wait_cqe() failed");
|
||||
}
|
||||
|
||||
return cqe;
|
||||
}
|
||||
|
||||
struct io_uring_cqe *
|
||||
Ring::PeekCompletion()
|
||||
{
|
||||
struct io_uring_cqe *cqe;
|
||||
int error = io_uring_peek_cqe(&ring, &cqe);
|
||||
if (error < 0) {
|
||||
if (error == -EAGAIN)
|
||||
return nullptr;
|
||||
|
||||
throw MakeErrno(-error, "io_uring_peek_cqe() failed");
|
||||
}
|
||||
|
||||
return cqe;
|
||||
}
|
||||
|
||||
} // namespace Uring
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright 2020 CM4all GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* author: Max Kellermann <mk@cm4all.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "io/FileDescriptor.hxx"
|
||||
|
||||
#include <liburing.h>
|
||||
|
||||
namespace Uring {
|
||||
|
||||
/**
|
||||
* Low-level C++ wrapper for a `struct io_uring`. It provides simple
|
||||
* wrappers to liburing functions and throws std::system_error on
|
||||
* errors.
|
||||
*/
|
||||
class Ring {
|
||||
struct io_uring ring;
|
||||
|
||||
public:
|
||||
Ring(unsigned entries, unsigned flags);
|
||||
|
||||
~Ring() noexcept {
|
||||
io_uring_queue_exit(&ring);
|
||||
}
|
||||
|
||||
Ring(const Ring &) = delete;
|
||||
Ring &operator=(const Ring &) = delete;
|
||||
|
||||
FileDescriptor GetFileDescriptor() const noexcept {
|
||||
return FileDescriptor(ring.ring_fd);
|
||||
}
|
||||
|
||||
struct io_uring_sqe *GetSubmitEntry() noexcept {
|
||||
return io_uring_get_sqe(&ring);
|
||||
}
|
||||
|
||||
void Submit();
|
||||
|
||||
struct io_uring_cqe *WaitCompletion();
|
||||
|
||||
/**
|
||||
* @return a completion queue entry or nullptr on EAGAIN
|
||||
*/
|
||||
struct io_uring_cqe *PeekCompletion();
|
||||
|
||||
void SeenCompletion(struct io_uring_cqe &cqe) noexcept {
|
||||
io_uring_cqe_seen(&ring, &cqe);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Uring
|
|
@ -0,0 +1,36 @@
|
|||
uring_features = configuration_data()
|
||||
|
||||
if host_machine.system() != 'linux'
|
||||
uring_dep = dependency('', required: false)
|
||||
uring_features.set('HAVE_URING', false)
|
||||
configure_file(output: 'Features.h', configuration: uring_features)
|
||||
subdir_done()
|
||||
endif
|
||||
|
||||
liburing = dependency('liburing', required: get_option('io_uring'))
|
||||
uring_features.set('HAVE_URING', liburing.found())
|
||||
configure_file(output: 'Features.h', configuration: uring_features)
|
||||
|
||||
if not liburing.found()
|
||||
uring_dep = dependency('', required: false)
|
||||
subdir_done()
|
||||
endif
|
||||
|
||||
uring = static_library(
|
||||
'uring',
|
||||
'Ring.cxx',
|
||||
'Queue.cxx',
|
||||
'Operation.cxx',
|
||||
include_directories: inc,
|
||||
dependencies: [
|
||||
liburing,
|
||||
],
|
||||
)
|
||||
|
||||
uring_dep = declare_dependency(
|
||||
link_with: uring,
|
||||
dependencies: [
|
||||
liburing,
|
||||
io_dep,
|
||||
],
|
||||
)
|
Loading…
Reference in New Issue