io/uring/Queue: add method RequireSubmitEntry()
Fixes assertion failure when the submit queue is empty.
This commit is contained in:
parent
c8f174ac92
commit
799032505e
@ -34,6 +34,8 @@
|
|||||||
#include "CancellableOperation.hxx"
|
#include "CancellableOperation.hxx"
|
||||||
#include "util/DeleteDisposer.hxx"
|
#include "util/DeleteDisposer.hxx"
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
namespace Uring {
|
namespace Uring {
|
||||||
|
|
||||||
Queue::Queue(unsigned entries, unsigned flags)
|
Queue::Queue(unsigned entries, unsigned flags)
|
||||||
@ -46,6 +48,23 @@ Queue::~Queue() noexcept
|
|||||||
operations.clear_and_dispose(DeleteDisposer{});
|
operations.clear_and_dispose(DeleteDisposer{});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct io_uring_sqe &
|
||||||
|
Queue::RequireSubmitEntry()
|
||||||
|
{
|
||||||
|
auto *sqe = GetSubmitEntry();
|
||||||
|
if (sqe == nullptr) {
|
||||||
|
/* the submit queue is full; submit it to the kernel
|
||||||
|
and try again */
|
||||||
|
Submit();
|
||||||
|
|
||||||
|
sqe = GetSubmitEntry();
|
||||||
|
if (sqe == nullptr)
|
||||||
|
throw std::runtime_error{"io_uring_get_sqe() failed"};
|
||||||
|
}
|
||||||
|
|
||||||
|
return *sqe;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Queue::AddPending(struct io_uring_sqe &sqe,
|
Queue::AddPending(struct io_uring_sqe &sqe,
|
||||||
Operation &operation) noexcept
|
Operation &operation) noexcept
|
||||||
|
@ -63,6 +63,14 @@ public:
|
|||||||
return ring.GetSubmitEntry();
|
return ring.GetSubmitEntry();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Like GetSubmitEntry(), but call Submit() if the submit
|
||||||
|
* queue is full.
|
||||||
|
*
|
||||||
|
* May throw exceptions if Submit() fails.
|
||||||
|
*/
|
||||||
|
struct io_uring_sqe &RequireSubmitEntry();
|
||||||
|
|
||||||
bool HasPending() const noexcept {
|
bool HasPending() const noexcept {
|
||||||
return !operations.empty();
|
return !operations.empty();
|
||||||
}
|
}
|
||||||
|
@ -45,14 +45,13 @@ ReadOperation::Start(Queue &queue, FileDescriptor fd, off_t offset,
|
|||||||
|
|
||||||
buffer = std::make_unique<std::byte[]>(size);
|
buffer = std::make_unique<std::byte[]>(size);
|
||||||
|
|
||||||
auto *s = queue.GetSubmitEntry();
|
auto &s = queue.RequireSubmitEntry();
|
||||||
assert(s != nullptr); // TODO: what if the submit queue is full?
|
|
||||||
|
|
||||||
iov.iov_base = buffer.get();
|
iov.iov_base = buffer.get();
|
||||||
iov.iov_len = size;
|
iov.iov_len = size;
|
||||||
|
|
||||||
io_uring_prep_readv(s, fd.Get(), &iov, 1, offset);
|
io_uring_prep_readv(&s, fd.Get(), &iov, 1, offset);
|
||||||
queue.Push(*s, *this);
|
queue.Push(s, *this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
Loading…
Reference in New Issue
Block a user