Skip to content

Commit 7a20cb2

Browse files
authored
complete ops inline on start failure (#190)
* remove internal check_cqe32() * check if runtime exist * check if already canceled * add tests
1 parent 9742c9f commit 7a20cb2

6 files changed

Lines changed: 72 additions & 35 deletions

File tree

‎include/condy/cqe_handler.hpp‎

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,6 @@ class SelectBufferCQEHandler {
5757
*/
5858
struct NVMePassthruCQEHandler {
5959
std::pair<int32_t, uint64_t> operator()(io_uring_cqe *cqe) noexcept {
60-
assert(
61-
detail::Context::current().runtime()->ring_internal().check_cqe32(
62-
cqe) &&
63-
"Expected big CQE for NVMe passthrough");
6460
return {cqe->res, cqe->big_cqe[0]};
6561
}
6662
};
@@ -98,10 +94,6 @@ struct SCSIBsgResult {
9894
*/
9995
struct SCSIBsgPassthruCQEHandler {
10096
std::pair<int32_t, SCSIBsgResult> operator()(io_uring_cqe *cqe) noexcept {
101-
assert(
102-
detail::Context::current().runtime()->ring_internal().check_cqe32(
103-
cqe) &&
104-
"Expected big CQE for SCSI BSG passthrough");
10597
return {cqe->res, SCSIBsgResult{cqe->big_cqe[0]}};
10698
}
10799
};
@@ -138,10 +130,6 @@ struct TxTimestampResult {
138130
struct TxTimestampCQEHandler {
139131
std::pair<int32_t, TxTimestampResult>
140132
operator()(io_uring_cqe *cqe) noexcept {
141-
assert(
142-
detail::Context::current().runtime()->ring_internal().check_cqe32(
143-
cqe) &&
144-
"Expected big CQE for TX timestamp operations");
145133
TxTimestampResult result;
146134
result.tstype =
147135
static_cast<int>(cqe->flags >> IORING_TIMESTAMP_TYPE_SHIFT);

‎include/condy/detail/finish_handles.hpp‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ class OpFinishHandle : public OpFinishHandleBase {
3232
CONDY_DELETE_COPY_MOVE(OpFinishHandle);
3333

3434
public:
35+
bool stop_requested() noexcept {
36+
auto stop_token = receiver_.get_stop_token();
37+
return stop_token.stop_requested();
38+
}
39+
3540
void maybe_set_cancel(Runtime *runtime) noexcept {
3641
auto stop_token = receiver_.get_stop_token();
3742
if (stop_token.stop_possible()) {

‎include/condy/detail/op_states.hpp‎

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,22 +31,36 @@ template <typename Handle, PrepFuncLike Func> class OpSenderOperationState {
3131

3232
public:
3333
void start(unsigned int flags) noexcept {
34-
auto &context = Context::current();
35-
auto &ring = context.runtime()->ring_internal();
34+
auto *runtime = Context::current().runtime();
35+
if (runtime == nullptr) {
36+
fail_(-EINVAL);
37+
return;
38+
}
39+
if (finish_handle_.get().stop_requested()) {
40+
fail_(-ECANCELED);
41+
return;
42+
}
43+
auto &ring = runtime->ring_internal();
3644
io_uring_sqe *sqe = prep_func_(&ring);
3745
if (sqe == nullptr) {
38-
io_uring_cqe cqe = {};
39-
cqe.res = -EINVAL;
40-
finish_handle_.get().handle(&cqe);
46+
fail_(-EINVAL);
4147
return;
4248
}
43-
context.runtime()->pend_work_internal();
49+
runtime->pend_work_internal();
4450
io_uring_sqe_set_flags(sqe, sqe->flags | flags);
4551
auto work = encode_work(&finish_handle_.get(), WorkType::Common);
4652
io_uring_sqe_set_data64(sqe, work);
4753
ring.maybe_submit();
4854

49-
finish_handle_.get().maybe_set_cancel(context.runtime());
55+
finish_handle_.get().maybe_set_cancel(runtime);
56+
}
57+
58+
private:
59+
void fail_(int32_t res) noexcept {
60+
assert(res < 0);
61+
io_uring_cqe cqe[2] = {};
62+
cqe[0].res = res;
63+
finish_handle_.get().handle(cqe);
5064
}
5165

5266
private:

‎include/condy/detail/ring.hpp‎

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -133,19 +133,6 @@ class Ring {
133133
}
134134
#endif
135135

136-
bool check_cqe32([[maybe_unused]] io_uring_cqe *cqe) const noexcept {
137-
auto ring_flags = ring_.flags;
138-
if (ring_flags & IORING_SETUP_CQE32) {
139-
return true;
140-
}
141-
#if CONDY_URING_VERSION_GE(2, 13) // >= 2.13
142-
if (ring_flags & IORING_SETUP_CQE_MIXED) {
143-
return cqe->flags & IORING_CQE_F_32;
144-
}
145-
#endif
146-
return false;
147-
}
148-
149136
private:
150137
template <io_uring_sqe *(*get_sqe)(struct io_uring *)>
151138
io_uring_sqe *get_sqe_() noexcept {

‎include/condy/zcrx.hpp‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,8 +203,6 @@ class ZeroCopyRxBufferPool {
203203
uint32_t zcrx_id() const noexcept { return zcrx_id_; }
204204

205205
ZeroCopyRxBuffer handle_finish(io_uring_cqe *cqe) noexcept {
206-
assert(ring_->check_cqe32(cqe) && "Expected big CQE for ZeroCopyRx");
207-
208206
if (cqe->res < 0) {
209207
return ZeroCopyRxBuffer();
210208
}

‎tests/test_senders.cpp‎

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#include "condy/async_operations.hpp"
12
#include "condy/awaiter_operations.hpp"
23
#include "condy/channel.hpp"
34
#include "condy/detail/async_operations.hpp"
@@ -6,7 +7,9 @@
67
#include "condy/sync_wait.hpp"
78
#include <atomic>
89
#include <cassert>
10+
#include <cerrno>
911
#include <doctest.h>
12+
#include <optional>
1013
#include <stdexcept>
1114
#include <stop_token>
1215
#include <thread>
@@ -557,4 +560,46 @@ TEST_CASE("test senders - cancel from other runtime thread") {
557560
condy::sync_wait(cancel_task());
558561

559562
t1.join();
560-
}
563+
}
564+
565+
TEST_CASE("test senders - start without runtime") {
566+
auto coro = []() -> condy::Coro<int> {
567+
int r = co_await condy::async_nop();
568+
REQUIRE(r == -EINVAL);
569+
co_return r;
570+
}();
571+
auto handle = coro.release();
572+
573+
REQUIRE(!handle.done());
574+
handle.resume();
575+
REQUIRE(handle.done());
576+
REQUIRE(handle.promise().value() == -EINVAL);
577+
578+
handle.destroy();
579+
}
580+
581+
#if CONDY_URING_VERSION_GE(2, 13) // >= 2.13
582+
TEST_CASE("test senders - start without sqe128 support") {
583+
auto func = []() -> condy::Coro<void> {
584+
int r = co_await condy::async_nop128();
585+
REQUIRE(r == -EINVAL);
586+
};
587+
condy::sync_wait(func());
588+
}
589+
#endif
590+
591+
TEST_CASE("test senders - start with stopped token") {
592+
using condy::operators::operator||;
593+
594+
auto func = []() -> condy::Coro<void> {
595+
condy::Channel<int> ch(1);
596+
REQUIRE(ch.try_push(42) == 0);
597+
598+
auto res = co_await (ch.pop() || condy::async_nop());
599+
REQUIRE(res.index() == 0);
600+
auto [r, item] = std::get<0>(res);
601+
REQUIRE(r == 0);
602+
REQUIRE(item == 42);
603+
};
604+
condy::sync_wait(func());
605+
}

0 commit comments

Comments
 (0)