#include "include/ceph_assert.h"
#include "include/Context.h"
#include "common/zipkin_trace.h"
+#include "common/RefCountedObj.h"
#include <atomic>
#include <type_traits>
}
};
+template <typename T, void (T::*MF)(int)>
+class C_RefCallbackAdapter : public Context {
+ RefCountedPtr refptr;
+ Context *on_finish;
+
+public:
+ C_RefCallbackAdapter(T *obj, RefCountedPtr refptr)
+ : refptr(std::move(refptr)),
+ on_finish(new C_CallbackAdapter<T, MF>(obj)) {
+ }
+
+protected:
+ void finish(int r) override {
+ on_finish->complete(r);
+ }
+};
+
template <typename T, Context*(T::*MF)(int*), bool destroy>
class C_StateCallbackAdapter : public Context {
T *obj;
}
};
+template <typename T, Context*(T::*MF)(int*)>
+class C_RefStateCallbackAdapter : public Context {
+ RefCountedPtr refptr;
+ Context *on_finish;
+
+public:
+ C_RefStateCallbackAdapter(T *obj, RefCountedPtr refptr)
+ : refptr(std::move(refptr)),
+ on_finish(new C_StateCallbackAdapter<T, MF, true>(obj)) {
+ }
+
+protected:
+ void finish(int r) override {
+ on_finish->complete(r);
+ }
+};
+
template <typename WQ>
struct C_AsyncCallback : public Context {
WQ *op_work_queue;
return new detail::C_StateCallbackAdapter<T, MF, destroy>(obj);
}
+//for reference counting objects
+template <typename T, void(T::*MF)(int) = &T::complete>
+Context *create_context_callback(T *obj, RefCountedPtr refptr) {
+ return new detail::C_RefCallbackAdapter<T, MF>(obj, refptr);
+}
+
+template <typename T, Context*(T::*MF)(int*)>
+Context *create_context_callback(T *obj, RefCountedPtr refptr) {
+ return new detail::C_RefStateCallbackAdapter<T, MF>(obj, refptr);
+}
+
+//for objects that don't inherit from RefCountedObj, to handle unit tests
+template <typename T, void(T::*MF)(int) = &T::complete, typename R>
+typename std::enable_if<not std::is_base_of<RefCountedPtr, R>::value, Context*>::type
+create_context_callback(T *obj, R *refptr) {
+ return new detail::C_CallbackAdapter<T, MF>(obj);
+}
+
+template <typename T, Context*(T::*MF)(int*), typename R, bool destroy=true>
+typename std::enable_if<not std::is_base_of<RefCountedPtr, R>::value, Context*>::type
+create_context_callback(T *obj, R *refptr) {
+ return new detail::C_StateCallbackAdapter<T, MF, destroy>(obj);
+}
+
template <typename I>
Context *create_async_context_callback(I &image_ctx, Context *on_finish) {
// use async callback to acquire a clean lock context