summaryrefslogtreecommitdiffstats
path: root/src/librados/AioCompletionImpl.h
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 18:24:20 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 18:24:20 +0000
commit483eb2f56657e8e7f419ab1a4fab8dce9ade8609 (patch)
treee5d88d25d870d5dedacb6bbdbe2a966086a0a5cf /src/librados/AioCompletionImpl.h
parentInitial commit. (diff)
downloadceph-483eb2f56657e8e7f419ab1a4fab8dce9ade8609.tar.xz
ceph-483eb2f56657e8e7f419ab1a4fab8dce9ade8609.zip
Adding upstream version 14.2.21.upstream/14.2.21upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/librados/AioCompletionImpl.h')
-rw-r--r--src/librados/AioCompletionImpl.h223
1 files changed, 223 insertions, 0 deletions
diff --git a/src/librados/AioCompletionImpl.h b/src/librados/AioCompletionImpl.h
new file mode 100644
index 00000000..98fa4e0c
--- /dev/null
+++ b/src/librados/AioCompletionImpl.h
@@ -0,0 +1,223 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2012 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_LIBRADOS_AIOCOMPLETIONIMPL_H
+#define CEPH_LIBRADOS_AIOCOMPLETIONIMPL_H
+
+#include "common/Cond.h"
+#include "common/Mutex.h"
+
+#include "include/buffer.h"
+#include "include/xlist.h"
+#include "osd/osd_types.h"
+
+class IoCtxImpl;
+
+struct librados::AioCompletionImpl {
+ Mutex lock;
+ Cond cond;
+ int ref, rval;
+ bool released;
+ bool complete;
+ version_t objver;
+ ceph_tid_t tid;
+
+ rados_callback_t callback_complete, callback_safe;
+ void *callback_complete_arg, *callback_safe_arg;
+
+ // for read
+ bool is_read;
+ bufferlist bl;
+ bufferlist *blp;
+ char *out_buf;
+
+ IoCtxImpl *io;
+ ceph_tid_t aio_write_seq;
+ xlist<AioCompletionImpl*>::item aio_write_list_item;
+
+ AioCompletionImpl() : lock("AioCompletionImpl lock", false, false),
+ ref(1), rval(0), released(false),
+ complete(false),
+ objver(0),
+ tid(0),
+ callback_complete(0),
+ callback_safe(0),
+ callback_complete_arg(0),
+ callback_safe_arg(0),
+ is_read(false), blp(nullptr), out_buf(nullptr),
+ io(NULL), aio_write_seq(0), aio_write_list_item(this) { }
+
+ int set_complete_callback(void *cb_arg, rados_callback_t cb) {
+ lock.Lock();
+ callback_complete = cb;
+ callback_complete_arg = cb_arg;
+ lock.Unlock();
+ return 0;
+ }
+ int set_safe_callback(void *cb_arg, rados_callback_t cb) {
+ lock.Lock();
+ callback_safe = cb;
+ callback_safe_arg = cb_arg;
+ lock.Unlock();
+ return 0;
+ }
+ int wait_for_complete() {
+ lock.Lock();
+ while (!complete)
+ cond.Wait(lock);
+ lock.Unlock();
+ return 0;
+ }
+ int wait_for_safe() {
+ return wait_for_complete();
+ }
+ int is_complete() {
+ lock.Lock();
+ int r = complete;
+ lock.Unlock();
+ return r;
+ }
+ int is_safe() {
+ return is_complete();
+ }
+ int wait_for_complete_and_cb() {
+ lock.Lock();
+ while (!complete || callback_complete || callback_safe)
+ cond.Wait(lock);
+ lock.Unlock();
+ return 0;
+ }
+ int wait_for_safe_and_cb() {
+ return wait_for_complete_and_cb();
+ }
+ int is_complete_and_cb() {
+ lock.Lock();
+ int r = complete && !callback_complete && !callback_safe;
+ lock.Unlock();
+ return r;
+ }
+ int is_safe_and_cb() {
+ return is_complete_and_cb();
+ }
+ int get_return_value() {
+ lock.Lock();
+ int r = rval;
+ lock.Unlock();
+ return r;
+ }
+ uint64_t get_version() {
+ lock.Lock();
+ version_t v = objver;
+ lock.Unlock();
+ return v;
+ }
+
+ void get() {
+ lock.Lock();
+ _get();
+ lock.Unlock();
+ }
+ void _get() {
+ ceph_assert(lock.is_locked());
+ ceph_assert(ref > 0);
+ ++ref;
+ }
+ void release() {
+ lock.Lock();
+ ceph_assert(!released);
+ released = true;
+ put_unlock();
+ }
+ void put() {
+ lock.Lock();
+ put_unlock();
+ }
+ void put_unlock() {
+ ceph_assert(ref > 0);
+ int n = --ref;
+ lock.Unlock();
+ if (!n)
+ delete this;
+ }
+};
+
+namespace librados {
+struct C_AioComplete : public Context {
+ AioCompletionImpl *c;
+
+ explicit C_AioComplete(AioCompletionImpl *cc) : c(cc) {
+ c->_get();
+ }
+
+ void finish(int r) override {
+ rados_callback_t cb_complete = c->callback_complete;
+ void *cb_complete_arg = c->callback_complete_arg;
+ if (cb_complete)
+ cb_complete(c, cb_complete_arg);
+
+ rados_callback_t cb_safe = c->callback_safe;
+ void *cb_safe_arg = c->callback_safe_arg;
+ if (cb_safe)
+ cb_safe(c, cb_safe_arg);
+
+ c->lock.Lock();
+ c->callback_complete = NULL;
+ c->callback_safe = NULL;
+ c->cond.Signal();
+ c->put_unlock();
+ }
+};
+
+/**
+ * Fills in all completed request data, and calls both
+ * complete and safe callbacks if they exist.
+ *
+ * Not useful for usual I/O, but for special things like
+ * flush where we only want to wait for things to be safe,
+ * but allow users to specify any of the callbacks.
+ */
+struct C_AioCompleteAndSafe : public Context {
+ AioCompletionImpl *c;
+
+ explicit C_AioCompleteAndSafe(AioCompletionImpl *cc) : c(cc) {
+ c->get();
+ }
+
+ void finish(int r) override {
+ c->lock.Lock();
+ c->rval = r;
+ c->complete = true;
+ c->lock.Unlock();
+
+ rados_callback_t cb_complete = c->callback_complete;
+ void *cb_complete_arg = c->callback_complete_arg;
+ if (cb_complete)
+ cb_complete(c, cb_complete_arg);
+
+ rados_callback_t cb_safe = c->callback_safe;
+ void *cb_safe_arg = c->callback_safe_arg;
+ if (cb_safe)
+ cb_safe(c, cb_safe_arg);
+
+ c->lock.Lock();
+ c->callback_complete = NULL;
+ c->callback_safe = NULL;
+ c->cond.Signal();
+ c->put_unlock();
+ }
+};
+
+}
+
+#endif