]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: fix memory leak
authorYehuda Sadeh <yehuda@redhat.com>
Tue, 13 Jan 2015 21:31:39 +0000 (13:31 -0800)
committerYehuda Sadeh <yehuda@redhat.com>
Wed, 14 Jan 2015 03:21:32 +0000 (19:21 -0800)
We were iterating on both completion_objs, and completions assuming that
they follow each other. They don't do it. While at it, index completions
by id, so that we could update the completed objs correctly.

Signed-off-by: Yehuda Sadeh <yehuda@redhat.com>
src/cls/rgw/cls_rgw_client.cc
src/cls/rgw/cls_rgw_client.h

index 1f7ff4fc05e6bdcd51503bc1e0aaec3dd115ee7e..fa33dac24be25d2ad6fc6ddc84d13fcddf5a1405 100644 (file)
@@ -45,7 +45,7 @@ void BucketIndexAioManager::do_completion(int id) {
 
   map<int, librados::AioCompletion*>::iterator iter = pendings.find(id);
   assert(iter != pendings.end());
-  completions.push_back(iter->second);
+  completions[id] = iter->second;
   pendings.erase(iter);
 
   // If the caller needs a list of finished objects, store them
@@ -70,16 +70,18 @@ bool BucketIndexAioManager::wait_for_completions(int valid_ret_code,
   cond.Wait(lock);
 
   // Clear the completed AIOs
-  list<librados::AioCompletion*>::iterator iter = completions.begin();
-  map<int, string>::iterator liter = completion_objs.begin();
-  for (; iter != completions.end() && liter != completion_objs.end(); ++iter, ++liter) {
-    int r = (*iter)->get_return_value();
-    if (objs && r == 0) {
-      (*objs)[liter->first] = liter->second;
+  map<int, librados::AioCompletion*>::iterator iter = completions.begin();
+  for (; iter != completions.end(); ++iter) {
+    int r = iter->second->get_return_value();
+    if (objs && r == 0) { /* update list of successfully completed objs */
+      map<int, string>::iterator liter = completion_objs.find(iter->first);
+      if (liter != completion_objs.end()) {
+        (*objs)[liter->first] = liter->second;
+      }
     }
     if (ret_code && (r < 0 && r != valid_ret_code))
       (*ret_code) = r;
-    (*iter)->release();
+    iter->second->release();
   }
   if (num_completions)
     (*num_completions) = completions.size();
index c54b3330b5081099e77920e9c3e5a45387a3a93d..e0c527094b73c2cf3f9d07df67d469e39bb9d7c5 100644 (file)
@@ -30,7 +30,7 @@ struct BucketIndexAioArg : public RefCountedObject {
 class BucketIndexAioManager {
 private:
   map<int, librados::AioCompletion*> pendings;
-  list<librados::AioCompletion*> completions;
+  map<int, librados::AioCompletion*> completions;
   map<int, string> pending_objs;
   map<int, string> completion_objs;
   int next;
@@ -60,11 +60,9 @@ private:
    * @param oid        - the object id associated with the object, if it is NULL, we don't
    *                     track the object id per callback.
    */
-  void add_pending(int id, librados::AioCompletion* completion, string *oid = NULL) {
+  void add_pending(int id, librados::AioCompletion* completion, const string& oid) {
     pendings[id] = completion;
-    if (oid) {
-      pending_objs[id] = *oid;
-    }
+    pending_objs[id] = oid;
   }
 public:
   /*
@@ -100,7 +98,7 @@ public:
     librados::AioCompletion *c = librados::Rados::aio_create_completion((void*)arg, NULL, bucket_index_op_completion_cb);
     int r = io_ctx.aio_operate(oid, c, (librados::ObjectReadOperation*)op, NULL);
     if (r >= 0) {
-      add_pending(arg->id, c);
+      add_pending(arg->id, c, oid);
     }
     return r;
   }
@@ -114,7 +112,7 @@ public:
     librados::AioCompletion *c = librados::Rados::aio_create_completion((void*)arg, NULL, bucket_index_op_completion_cb);
     int r = io_ctx.aio_operate(oid, c, (librados::ObjectWriteOperation*)op);
     if (r >= 0) {
-      add_pending(arg->id, c);
+      add_pending(arg->id, c, oid);
     }
     return r;
   }
@@ -241,7 +239,8 @@ public:
 
     int num_completions, r = 0;
     map<int, string> objs;
-    while (manager.wait_for_completions(valid_ret_code(), &num_completions, &r, &objs)) {
+    map<int, string> *pobjs = (need_multiple_rounds() ? &objs : NULL);
+    while (manager.wait_for_completions(valid_ret_code(), &num_completions, &r, pobjs)) {
       if (r >= 0 && ret >= 0) {
         for(int i = 0; i < num_completions && iter != objs_container.end(); ++i, ++iter) {
           int issue_ret = issue_op(iter->first, iter->second);