diff --git a/meson.build b/meson.build index c4ba8a8c6..e78693ace 100644 --- a/meson.build +++ b/meson.build @@ -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') diff --git a/meson_options.txt b/meson_options.txt index d17ac1ca8..446fadccd 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -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') diff --git a/src/io/uring/CancellableOperation.hxx b/src/io/uring/CancellableOperation.hxx new file mode 100644 index 000000000..b55af5867 --- /dev/null +++ b/src/io/uring/CancellableOperation.hxx @@ -0,0 +1,81 @@ +/* + * Copyright 2020 CM4all GmbH + * All rights reserved. + * + * author: Max Kellermann + * + * 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 + +#include +#include + +namespace Uring { + +class CancellableOperation + : public boost::intrusive::list_base_hook> +{ + 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 diff --git a/src/io/uring/Handler.hxx b/src/io/uring/Handler.hxx new file mode 100644 index 000000000..ab170f1c6 --- /dev/null +++ b/src/io/uring/Handler.hxx @@ -0,0 +1,49 @@ +/* + * Copyright 2020 CM4all GmbH + * All rights reserved. + * + * author: Max Kellermann + * + * 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 + +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 diff --git a/src/io/uring/Operation.cxx b/src/io/uring/Operation.cxx new file mode 100644 index 000000000..cf8864e2d --- /dev/null +++ b/src/io/uring/Operation.cxx @@ -0,0 +1,47 @@ +/* + * Copyright 2020 CM4all GmbH + * All rights reserved. + * + * author: Max Kellermann + * + * 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 diff --git a/src/io/uring/Operation.hxx b/src/io/uring/Operation.hxx new file mode 100644 index 000000000..662d959f3 --- /dev/null +++ b/src/io/uring/Operation.hxx @@ -0,0 +1,58 @@ +/* + * Copyright 2020 CM4all GmbH + * All rights reserved. + * + * author: Max Kellermann + * + * 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 diff --git a/src/io/uring/Queue.cxx b/src/io/uring/Queue.cxx new file mode 100644 index 000000000..b5032e9dc --- /dev/null +++ b/src/io/uring/Queue.cxx @@ -0,0 +1,97 @@ +/* + * Copyright 2020 CM4all GmbH + * All rights reserved. + * + * author: Max Kellermann + * + * 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 + +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 diff --git a/src/io/uring/Queue.hxx b/src/io/uring/Queue.hxx new file mode 100644 index 000000000..b71a73c16 --- /dev/null +++ b/src/io/uring/Queue.hxx @@ -0,0 +1,104 @@ +/* + * Copyright 2020 CM4all GmbH + * All rights reserved. + * + * author: Max Kellermann + * + * 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 + +#include + +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>>, + boost::intrusive::constant_time_size> 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 diff --git a/src/io/uring/Ring.cxx b/src/io/uring/Ring.cxx new file mode 100644 index 000000000..89bd7b168 --- /dev/null +++ b/src/io/uring/Ring.cxx @@ -0,0 +1,83 @@ +/* + * Copyright 2020 CM4all GmbH + * All rights reserved. + * + * author: Max Kellermann + * + * 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 diff --git a/src/io/uring/Ring.hxx b/src/io/uring/Ring.hxx new file mode 100644 index 000000000..0a1f783d4 --- /dev/null +++ b/src/io/uring/Ring.hxx @@ -0,0 +1,81 @@ +/* + * Copyright 2020 CM4all GmbH + * All rights reserved. + * + * author: Max Kellermann + * + * 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 + +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 diff --git a/src/io/uring/meson.build b/src/io/uring/meson.build new file mode 100644 index 000000000..7d582be7d --- /dev/null +++ b/src/io/uring/meson.build @@ -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, + ], +)