[objecter = impl->objecter,
linger_op, c = std::move(c)]
(bs::error_code ec) mutable {
- objecter->linger_cancel(linger_op);
+ if (!ec) {
+ objecter->linger_cancel(linger_op);
+ }
asio::dispatch(asio::append(std::move(c), ec));
}));
}
#include "common/async/waiter.h"
#include "error_code.h"
+#include "neorados/RADOSImpl.h"
using std::list;
using std::make_pair;
}
}
+struct op_cancellation {
+ ceph_tid_t tid;
+ Objecter* objecter;
+
+ op_cancellation(ceph_tid_t tid, Objecter* objecter)
+ : tid(tid), objecter(objecter) {}
+
+ void operator ()(asio::cancellation_type_t type) {
+ if (type == asio::cancellation_type::total ||
+ type == asio::cancellation_type::terminal) {
+ // Since nobody can cancel until we return (I hope) we shouldn't
+ // need a mutex or anything.
+ objecter->op_cancel(tid, asio::error::operation_aborted);
+ }
+ }
+};
+
void Objecter::_op_submit(Op *op, shunique_lock<ceph::shared_mutex>& sul, ceph_tid_t *ptid)
{
// rwlock is locked
_session_op_assign(s, op);
+
+ auto compptr = std::get_if<Op::OpComp>(&op->onfinish);
+ if (compptr) {
+ // arrange for per-op cancellation
+ auto slot = boost::asio::get_associated_cancellation_slot(*compptr);
+ if (slot.is_connected()) {
+ slot.template emplace<op_cancellation>(op->tid, this);
+ }
+ }
+
if (need_send) {
_send_op(op);
}
#include <utility>
#include <boost/asio/use_awaitable.hpp>
+#include <boost/asio/experimental/awaitable_operators.hpp>
#include <boost/container/flat_map.hpp>
}
co_return;
}
+
+CORO_TEST_F(NeoRadosReadOps, Cancel, ReadOpTest) {
+ using namespace boost::asio::experimental::awaitable_operators;
+ auto bl = filled_buffer_list(0x33, 4 * 1 << 20);
+ co_await execute(oid, WriteOp{}.write_full(std::move(bl)));
+ co_await (execute(oid, ReadOp{}.read(0, 0, &bl)) || wait_for(1us));
+ co_return;
+}
#include <utility>
#include <boost/asio/use_awaitable.hpp>
+#include <boost/asio/experimental/awaitable_operators.hpp>
#include <boost/system/error_code.hpp>
#include <boost/system/errc.hpp>
}
co_return;
}
+
+CORO_TEST_F(NeoRadosWriteOps, Cancel, NeoRadosTest) {
+ using namespace boost::asio::experimental::awaitable_operators;
+ auto bl = filled_buffer_list(0x33, 4 * 1 << 20);
+ co_await (execute(oid, WriteOp{}.write_full(std::move(bl))) || wait_for(1us));
+ co_return;
+}