return 0;
}
-static void _mdlog_info_completion(librados::completion_t cb, void *arg);
-
-class RGWMetadataLogInfoCompletion : public RefCountedObject {
- RGWMetadataLogInfo *pinfo;
- RGWCompletionManager *completion_manager;
- void *user_info;
- int *pret;
- cls_log_header header;
- librados::IoCtx io_ctx;
- librados::AioCompletion *completion;
-
-public:
- RGWMetadataLogInfoCompletion(RGWMetadataLogInfo *_pinfo, RGWCompletionManager *_cm, void *_uinfo, int *_pret) :
- pinfo(_pinfo), completion_manager(_cm), user_info(_uinfo), pret(_pret) {
- completion = librados::Rados::aio_create_completion((void *)this, NULL,
- _mdlog_info_completion);
- }
-
- ~RGWMetadataLogInfoCompletion() {
- completion->release();
- }
-
- void finish(librados::completion_t cb) {
- *pret = completion->get_return_value();
- if (*pret >= 0) {
- pinfo->marker = header.max_marker;
- pinfo->last_update = header.max_time.to_real_time();
- }
- completion_manager->complete(NULL, user_info);
- put();
- }
-
- librados::IoCtx& get_io_ctx() { return io_ctx; }
-
- cls_log_header *get_header() {
- return &header;
- }
-
- librados::AioCompletion *get_completion() {
- return completion;
- }
-};
-
static void _mdlog_info_completion(librados::completion_t cb, void *arg)
{
- RGWMetadataLogInfoCompletion *infoc = (RGWMetadataLogInfoCompletion *)arg;
+ auto infoc = static_cast<RGWMetadataLogInfoCompletion *>(arg);
infoc->finish(cb);
+ infoc->put(); // drop the ref from get_info_async()
}
-int RGWMetadataLog::get_info_async(int shard_id, RGWMetadataLogInfo *info, RGWCompletionManager *completion_manager, void *user_info, int *pret)
+RGWMetadataLogInfoCompletion::RGWMetadataLogInfoCompletion(info_callback_t cb)
+ : completion(librados::Rados::aio_create_completion((void *)this, nullptr,
+ _mdlog_info_completion)),
+ callback(cb)
{
- string oid;
- get_shard_oid(shard_id, oid);
-
- RGWMetadataLogInfoCompletion *req_completion = new RGWMetadataLogInfoCompletion(info, completion_manager, user_info, pret);
+}
- req_completion->get();
+RGWMetadataLogInfoCompletion::~RGWMetadataLogInfoCompletion()
+{
+ completion->release();
+}
- int ret = store->time_log_info_async(req_completion->get_io_ctx(), oid, req_completion->get_header(), req_completion->get_completion());
- if (ret < 0) {
- return ret;
- }
+int RGWMetadataLog::get_info_async(int shard_id, RGWMetadataLogInfoCompletion *completion)
+{
+ string oid;
+ get_shard_oid(shard_id, oid);
- req_completion->put();
+ completion->get(); // hold a ref until the completion fires
- return 0;
+ return store->time_log_info_async(completion->get_io_ctx(), oid,
+ &completion->get_header(),
+ completion->get_completion());
}
int RGWMetadataLog::trim(int shard_id, const real_time& from_time, const real_time& end_time,
#define CEPH_RGW_METADATA_H
#include <string>
+#include <boost/optional.hpp>
#include "include/types.h"
#include "rgw_common.h"
#include "cls/version/cls_version_types.h"
#include "cls/log/cls_log_types.h"
#include "common/RWLock.h"
+#include "common/RefCountedObj.h"
#include "common/ceph_time.h"
class RGWCompletionManager;
+class RGWMetadataLogInfoCompletion : public RefCountedObject {
+ public:
+ using info_callback_t = std::function<void(int, const cls_log_header&)>;
+ private:
+ cls_log_header header;
+ librados::IoCtx io_ctx;
+ librados::AioCompletion *completion;
+ std::mutex mutex; //< protects callback between cancel/complete
+ boost::optional<info_callback_t> callback; //< cleared on cancel
+ public:
+ RGWMetadataLogInfoCompletion(info_callback_t callback);
+ virtual ~RGWMetadataLogInfoCompletion();
+
+ librados::IoCtx& get_io_ctx() { return io_ctx; }
+ cls_log_header& get_header() { return header; }
+ librados::AioCompletion* get_completion() { return completion; }
+
+ void finish(librados::completion_t cb) {
+ std::lock_guard<std::mutex> lock(mutex);
+ if (callback) {
+ (*callback)(completion->get_return_value(), header);
+ }
+ }
+ void cancel() {
+ std::lock_guard<std::mutex> lock(mutex);
+ callback = boost::none;
+ }
+};
+
class RGWMetadataLog {
CephContext *cct;
RGWRados *store;
int trim(int shard_id, const real_time& from_time, const real_time& end_time, const string& start_marker, const string& end_marker);
int get_info(int shard_id, RGWMetadataLogInfo *info);
- int get_info_async(int shard_id, RGWMetadataLogInfo *info, RGWCompletionManager *completion_manager, void *user_info, int *pret);
+ int get_info_async(int shard_id, RGWMetadataLogInfoCompletion *completion);
int lock_exclusive(int shard_id, timespan duration, string&zone_id, string& owner_id);
int unlock(int shard_id, string& zone_id, string& owner_id);