1616
1717#include " include/rados/librados.hpp"
1818#include " common/async/completion.h"
19+ #include " librados/AioCompletionImpl.h"
1920
2021// / Defines asynchronous librados operations that satisfy all of the
2122// / "Requirements on asynchronous operations" imposed by the C++ Networking TS
@@ -53,20 +54,20 @@ using unique_aio_completion_ptr =
5354// / argument to the handler.
5455template <typename Result>
5556struct Invoker {
56- using Signature = void (boost::system::error_code, Result);
57+ using Signature = void (boost::system::error_code, version_t , Result);
5758 Result result;
5859 template <typename Completion>
59- void dispatch (Completion&& completion, boost::system::error_code ec) {
60- ceph::async::dispatch (std::move (completion), ec, std::move (result));
60+ void dispatch (Completion&& completion, boost::system::error_code ec, version_t ver ) {
61+ ceph::async::dispatch (std::move (completion), ec, ver, std::move (result));
6162 }
6263};
6364// specialization for Result=void
6465template <>
6566struct Invoker <void > {
66- using Signature = void (boost::system::error_code);
67+ using Signature = void (boost::system::error_code, version_t );
6768 template <typename Completion>
68- void dispatch (Completion&& completion, boost::system::error_code ec) {
69- ceph::async::dispatch (std::move (completion), ec);
69+ void dispatch (Completion&& completion, boost::system::error_code ec, version_t ver ) {
70+ ceph::async::dispatch (std::move (completion), ec, ver );
7071 }
7172};
7273
@@ -82,12 +83,15 @@ struct AsyncOp : Invoker<Result> {
8283 auto p = std::unique_ptr<Completion>{static_cast <Completion*>(arg)};
8384 // move result out of Completion memory being freed
8485 auto op = std::move (p->user_data );
85- const int ret = op.aio_completion ->get_return_value ();
86+ // access AioCompletionImpl directly to avoid locking
87+ const librados::AioCompletionImpl* pc = op.aio_completion ->pc ;
88+ const int ret = pc->rval ;
89+ const version_t ver = pc->objver ;
8690 boost::system::error_code ec;
8791 if (ret < 0 ) {
8892 ec.assign (-ret, librados::detail::err_category ());
8993 }
90- op.dispatch (std::move (p), ec);
94+ op.dispatch (std::move (p), ec, ver );
9195 }
9296
9397 template <typename Executor1, typename CompletionHandler>
@@ -103,7 +107,7 @@ struct AsyncOp : Invoker<Result> {
103107
104108
105109// / Calls IoCtx::aio_read() and arranges for the AioCompletion to call a
106- // / given handler with signature (boost::system:: error_code, bufferlist).
110+ // / given handler with signature (error_code, version_t , bufferlist).
107111template <typename ExecutionContext, typename CompletionToken>
108112auto async_read (ExecutionContext& ctx, IoCtx& io, const std::string& oid,
109113 size_t len, uint64_t off, CompletionToken&& token)
@@ -119,40 +123,40 @@ auto async_read(ExecutionContext& ctx, IoCtx& io, const std::string& oid,
119123 int ret = io.aio_read (oid, op.aio_completion .get (), &op.result , len, off);
120124 if (ret < 0 ) {
121125 auto ec = boost::system::error_code{-ret, librados::detail::err_category ()};
122- ceph::async::post (std::move (p), ec, bufferlist{});
126+ ceph::async::post (std::move (p), ec, 0 , bufferlist{});
123127 } else {
124128 p.release (); // release ownership until completion
125129 }
126130 }, token, ctx.get_executor (), io, oid, len, off);
127131}
128132
129133// / Calls IoCtx::aio_write() and arranges for the AioCompletion to call a
130- // / given handler with signature (boost::system:: error_code).
134+ // / given handler with signature (error_code, version_t ).
131135template <typename ExecutionContext, typename CompletionToken>
132136auto async_write (ExecutionContext& ctx, IoCtx& io, const std::string& oid,
133- bufferlist &bl, size_t len, uint64_t off,
137+ const bufferlist &bl, size_t len, uint64_t off,
134138 CompletionToken&& token)
135139{
136140 using Op = detail::AsyncOp<void >;
137141 using Signature = typename Op::Signature;
138142 return boost::asio::async_initiate<CompletionToken, Signature>(
139143 [] (auto handler, auto ex, IoCtx& io, const std::string& oid,
140- bufferlist &bl, size_t len, uint64_t off) {
144+ const bufferlist &bl, size_t len, uint64_t off) {
141145 auto p = Op::create (ex, std::move (handler));
142146 auto & op = p->user_data ;
143147
144148 int ret = io.aio_write (oid, op.aio_completion .get (), bl, len, off);
145149 if (ret < 0 ) {
146150 auto ec = boost::system::error_code{-ret, librados::detail::err_category ()};
147- ceph::async::post (std::move (p), ec);
151+ ceph::async::post (std::move (p), ec, 0 );
148152 } else {
149153 p.release (); // release ownership until completion
150154 }
151155 }, token, ctx.get_executor (), io, oid, bl, len, off);
152156}
153157
154158// / Calls IoCtx::aio_operate() and arranges for the AioCompletion to call a
155- // / given handler with signature (boost::system:: error_code, bufferlist).
159+ // / given handler with signature (error_code, version_t , bufferlist).
156160template <typename ExecutionContext, typename CompletionToken>
157161auto async_operate (ExecutionContext& ctx, IoCtx& io, const std::string& oid,
158162 ObjectReadOperation *read_op, int flags,
@@ -170,15 +174,15 @@ auto async_operate(ExecutionContext& ctx, IoCtx& io, const std::string& oid,
170174 flags, &op.result );
171175 if (ret < 0 ) {
172176 auto ec = boost::system::error_code{-ret, librados::detail::err_category ()};
173- ceph::async::post (std::move (p), ec, bufferlist{});
177+ ceph::async::post (std::move (p), ec, 0 , bufferlist{});
174178 } else {
175179 p.release (); // release ownership until completion
176180 }
177181 }, token, ctx.get_executor (), io, oid, read_op, flags);
178182}
179183
180184// / Calls IoCtx::aio_operate() and arranges for the AioCompletion to call a
181- // / given handler with signature (boost::system:: error_code).
185+ // / given handler with signature (error_code, version_t ).
182186template <typename ExecutionContext, typename CompletionToken>
183187auto async_operate (ExecutionContext& ctx, IoCtx& io, const std::string& oid,
184188 ObjectWriteOperation *write_op, int flags,
@@ -196,15 +200,15 @@ auto async_operate(ExecutionContext& ctx, IoCtx& io, const std::string& oid,
196200 int ret = io.aio_operate (oid, op.aio_completion .get (), write_op, flags, trace_ctx);
197201 if (ret < 0 ) {
198202 auto ec = boost::system::error_code{-ret, librados::detail::err_category ()};
199- ceph::async::post (std::move (p), ec);
203+ ceph::async::post (std::move (p), ec, 0 );
200204 } else {
201205 p.release (); // release ownership until completion
202206 }
203207 }, token, ctx.get_executor (), io, oid, write_op, flags, trace_ctx);
204208}
205209
206210// / Calls IoCtx::aio_notify() and arranges for the AioCompletion to call a
207- // / given handler with signature (boost::system:: error_code, bufferlist).
211+ // / given handler with signature (error_code, version_t , bufferlist).
208212template <typename ExecutionContext, typename CompletionToken>
209213auto async_notify (ExecutionContext& ctx, IoCtx& io, const std::string& oid,
210214 bufferlist& bl, uint64_t timeout_ms, CompletionToken &&token)
@@ -221,7 +225,7 @@ auto async_notify(ExecutionContext& ctx, IoCtx& io, const std::string& oid,
221225 bl, timeout_ms, &op.result );
222226 if (ret < 0 ) {
223227 auto ec = boost::system::error_code{-ret, librados::detail::err_category ()};
224- ceph::async::post (std::move (p), ec, bufferlist{});
228+ ceph::async::post (std::move (p), ec, 0 , bufferlist{});
225229 } else {
226230 p.release (); // release ownership until completion
227231 }
0 commit comments