1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #ifndef CEPH_LIBRBD_IO_AIO_COMPLETION_H
5 #define CEPH_LIBRBD_IO_AIO_COMPLETION_H
7 #include "common/Cond.h"
8 #include "common/Mutex.h"
9 #include "include/Context.h"
10 #include "include/utime.h"
11 #include "include/rbd/librbd.hpp"
13 #include "librbd/ImageCtx.h"
14 #include "librbd/io/AsyncOperation.h"
15 #include "librbd/io/ReadResult.h"
16 #include "librbd/io/Types.h"
25 * AioCompletion is the overall completion for a single
26 * rbd I/O request. It may be composed of many AioObjectRequests,
27 * which each go to a single object.
29 * The retrying of individual requests is handled at a lower level,
30 * so all AioCompletion cares about is the count of outstanding
31 * requests. The number of expected individual requests should be
32 * set initially using set_request_count() prior to issuing the
33 * requests. This ensures that the completion will not be completed
34 * within the caller's thread of execution (instead via a librados
35 * context or via a thread pool context for cache read hits).
37 struct AioCompletion
{
39 AIO_STATE_PENDING
= 0,
48 callback_t complete_cb
;
50 rbd_completion_t rbd_comp
;
51 uint32_t pending_count
; ///< number of requests
59 ReadResult read_result
;
61 AsyncOperation async_op
;
64 xlist
<AioCompletion
*>::item m_xlist_item
;
67 template <typename T
, void (T::*MF
)(int)>
68 static void callback_adapter(completion_t cb
, void *arg
) {
69 AioCompletion
*comp
= reinterpret_cast<AioCompletion
*>(cb
);
70 T
*t
= reinterpret_cast<T
*>(arg
);
71 (t
->*MF
)(comp
->get_return_value());
75 static AioCompletion
*create(void *cb_arg
, callback_t cb_complete
,
76 rbd_completion_t rbd_comp
) {
77 AioCompletion
*comp
= new AioCompletion();
78 comp
->set_complete_cb(cb_arg
, cb_complete
);
79 comp
->rbd_comp
= (rbd_comp
!= nullptr ? rbd_comp
: comp
);
83 template <typename T
, void (T::*MF
)(int) = &T::complete
>
84 static AioCompletion
*create(T
*obj
) {
85 AioCompletion
*comp
= new AioCompletion();
86 comp
->set_complete_cb(obj
, &callback_adapter
<T
, MF
>);
87 comp
->rbd_comp
= comp
;
91 template <typename T
, void (T::*MF
)(int) = &T::complete
>
92 static AioCompletion
*create_and_start(T
*obj
, ImageCtx
*image_ctx
,
94 AioCompletion
*comp
= create
<T
, MF
>(obj
);
95 comp
->init_time(image_ctx
, type
);
100 AioCompletion() : lock("AioCompletion::lock", true, false),
101 state(AIO_STATE_PENDING
), rval(0), complete_cb(NULL
),
102 complete_arg(NULL
), rbd_comp(NULL
),
103 pending_count(0), blockers(1),
104 ref(1), released(false), ictx(NULL
),
105 aio_type(AIO_TYPE_NONE
),
106 journal_tid(0), m_xlist_item(this), event_notify(false) {
112 int wait_for_complete();
114 void finalize(ssize_t rval
);
116 inline bool is_initialized(aio_type_t type
) const {
117 Mutex::Locker
locker(lock
);
118 return ((ictx
!= nullptr) && (aio_type
== type
));
120 inline bool is_started() const {
121 Mutex::Locker
locker(lock
);
122 return async_op
.started();
125 void init_time(ImageCtx
*i
, aio_type_t t
);
126 void start_op(bool ignore_type
= false);
131 void set_complete_cb(void *cb_arg
, callback_t cb
) {
133 complete_arg
= cb_arg
;
136 void set_request_count(uint32_t num
);
139 assert(pending_count
> 0);
143 void complete_request(ssize_t r
);
145 void associate_journal_event(uint64_t tid
);
149 ssize_t
get_return_value();
174 ictx
->completed_reqs_lock
.Lock();
175 m_xlist_item
.remove_myself();
176 ictx
->completed_reqs_lock
.Unlock();
178 if (aio_type
== AIO_TYPE_CLOSE
||
179 (aio_type
== AIO_TYPE_OPEN
&& rval
< 0)) {
188 Mutex::Locker
l(lock
);
192 Mutex::Locker
l(lock
);
193 assert(blockers
> 0);
195 if (pending_count
== 0 && blockers
== 0) {
201 void set_event_notify(bool s
) {
202 Mutex::Locker
l(lock
);
211 class C_AioRequest
: public Context
{
213 C_AioRequest(AioCompletion
*completion
) : m_completion(completion
) {
214 m_completion
->add_request();
216 ~C_AioRequest() override
{}
217 void finish(int r
) override
{
218 m_completion
->complete_request(r
);
221 AioCompletion
*m_completion
;
225 } // namespace librbd
227 #endif // CEPH_LIBRBD_IO_AIO_COMPLETION_H