]> git.proxmox.com Git - ceph.git/blob - ceph/src/librados/AioCompletionImpl.h
update sources to 12.2.7
[ceph.git] / ceph / src / librados / AioCompletionImpl.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 /*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2004-2012 Sage Weil <sage@newdream.net>
7 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
12 *
13 */
14
15 #ifndef CEPH_LIBRADOS_AIOCOMPLETIONIMPL_H
16 #define CEPH_LIBRADOS_AIOCOMPLETIONIMPL_H
17
18 #include "common/Cond.h"
19 #include "common/Mutex.h"
20
21 #include "include/buffer.h"
22 #include "include/rados/librados.h"
23 #include "include/rados/librados.hpp"
24 #include "include/xlist.h"
25 #include "osd/osd_types.h"
26
27 class IoCtxImpl;
28
29 struct librados::AioCompletionImpl {
30 Mutex lock;
31 Cond cond;
32 int ref, rval;
33 bool released;
34 bool complete;
35 version_t objver;
36 ceph_tid_t tid;
37
38 rados_callback_t callback_complete, callback_safe;
39 void *callback_complete_arg, *callback_safe_arg;
40
41 // for read
42 bool is_read;
43 bufferlist bl;
44 bufferlist *blp;
45 char *out_buf;
46
47 IoCtxImpl *io;
48 ceph_tid_t aio_write_seq;
49 xlist<AioCompletionImpl*>::item aio_write_list_item;
50
51 AioCompletionImpl() : lock("AioCompletionImpl lock", false, false),
52 ref(1), rval(0), released(false),
53 complete(false),
54 objver(0),
55 tid(0),
56 callback_complete(0),
57 callback_safe(0),
58 callback_complete_arg(0),
59 callback_safe_arg(0),
60 is_read(false), blp(nullptr), out_buf(nullptr),
61 io(NULL), aio_write_seq(0), aio_write_list_item(this) { }
62
63 int set_complete_callback(void *cb_arg, rados_callback_t cb) {
64 lock.Lock();
65 callback_complete = cb;
66 callback_complete_arg = cb_arg;
67 lock.Unlock();
68 return 0;
69 }
70 int set_safe_callback(void *cb_arg, rados_callback_t cb) {
71 lock.Lock();
72 callback_safe = cb;
73 callback_safe_arg = cb_arg;
74 lock.Unlock();
75 return 0;
76 }
77 int wait_for_complete() {
78 lock.Lock();
79 while (!complete)
80 cond.Wait(lock);
81 lock.Unlock();
82 return 0;
83 }
84 int wait_for_safe() {
85 return wait_for_complete();
86 }
87 int is_complete() {
88 lock.Lock();
89 int r = complete;
90 lock.Unlock();
91 return r;
92 }
93 int is_safe() {
94 return is_complete();
95 }
96 int wait_for_complete_and_cb() {
97 lock.Lock();
98 while (!complete || callback_complete || callback_safe)
99 cond.Wait(lock);
100 lock.Unlock();
101 return 0;
102 }
103 int wait_for_safe_and_cb() {
104 return wait_for_complete_and_cb();
105 }
106 int is_complete_and_cb() {
107 lock.Lock();
108 int r = complete && !callback_complete && !callback_safe;
109 lock.Unlock();
110 return r;
111 }
112 int is_safe_and_cb() {
113 return is_complete_and_cb();
114 }
115 int get_return_value() {
116 lock.Lock();
117 int r = rval;
118 lock.Unlock();
119 return r;
120 }
121 uint64_t get_version() {
122 lock.Lock();
123 version_t v = objver;
124 lock.Unlock();
125 return v;
126 }
127
128 void get() {
129 lock.Lock();
130 _get();
131 lock.Unlock();
132 }
133 void _get() {
134 assert(lock.is_locked());
135 assert(ref > 0);
136 ++ref;
137 }
138 void release() {
139 lock.Lock();
140 assert(!released);
141 released = true;
142 put_unlock();
143 }
144 void put() {
145 lock.Lock();
146 put_unlock();
147 }
148 void put_unlock() {
149 assert(ref > 0);
150 int n = --ref;
151 lock.Unlock();
152 if (!n)
153 delete this;
154 }
155 };
156
157 namespace librados {
158 struct C_AioComplete : public Context {
159 AioCompletionImpl *c;
160
161 explicit C_AioComplete(AioCompletionImpl *cc) : c(cc) {
162 c->_get();
163 }
164
165 void finish(int r) override {
166 rados_callback_t cb_complete = c->callback_complete;
167 void *cb_complete_arg = c->callback_complete_arg;
168 if (cb_complete)
169 cb_complete(c, cb_complete_arg);
170
171 rados_callback_t cb_safe = c->callback_safe;
172 void *cb_safe_arg = c->callback_safe_arg;
173 if (cb_safe)
174 cb_safe(c, cb_safe_arg);
175
176 c->lock.Lock();
177 c->callback_complete = NULL;
178 c->callback_safe = NULL;
179 c->cond.Signal();
180 c->put_unlock();
181 }
182 };
183
184 /**
185 * Fills in all completed request data, and calls both
186 * complete and safe callbacks if they exist.
187 *
188 * Not useful for usual I/O, but for special things like
189 * flush where we only want to wait for things to be safe,
190 * but allow users to specify any of the callbacks.
191 */
192 struct C_AioCompleteAndSafe : public Context {
193 AioCompletionImpl *c;
194
195 explicit C_AioCompleteAndSafe(AioCompletionImpl *cc) : c(cc) {
196 c->get();
197 }
198
199 void finish(int r) override {
200 c->lock.Lock();
201 c->rval = r;
202 c->complete = true;
203 c->lock.Unlock();
204
205 rados_callback_t cb_complete = c->callback_complete;
206 void *cb_complete_arg = c->callback_complete_arg;
207 if (cb_complete)
208 cb_complete(c, cb_complete_arg);
209
210 rados_callback_t cb_safe = c->callback_safe;
211 void *cb_safe_arg = c->callback_safe_arg;
212 if (cb_safe)
213 cb_safe(c, cb_safe_arg);
214
215 c->lock.Lock();
216 c->callback_complete = NULL;
217 c->callback_safe = NULL;
218 c->cond.Signal();
219 c->put_unlock();
220 }
221 };
222
223 }
224
225 #endif