]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
CephContext: Add AssociatedSingletonObject to allow CephContext's singleton
authorHaomai Wang <haomaiwang@gmail.com>
Mon, 1 Dec 2014 15:54:16 +0000 (23:54 +0800)
committerHaomai Wang <haomaiwang@gmail.com>
Mon, 1 Dec 2014 17:23:15 +0000 (01:23 +0800)
If some objects associated to CephContext want to create a singleton object,
it can inherit AssociatedSingletonObject and implement destruction to get notified.

Signed-off-by: Haomai Wang <haomaiwang@gmail.com>
src/common/ceph_context.cc
src/common/ceph_context.h

index 4816acb334d7e8a9328882485fd8de682afd8678..36c04244de132840407b9fe3b6229b30337ca671 100644 (file)
@@ -297,6 +297,7 @@ CephContext::CephContext(uint32_t module_type_)
     _crypto_aes(NULL)
 {
   ceph_spin_init(&_service_thread_lock);
+  ceph_spin_init(&_associated_objs_lock);
 
   _log = new ceph::log::Log(&_conf->subsys);
   _log->start();
@@ -333,6 +334,10 @@ CephContext::~CephContext()
 {
   join_service_thread();
 
+  for (map<string, AssociatedSingletonObject*>::iterator it = _associated_objs.begin();
+       it != _associated_objs.end(); it++)
+    delete it->second;
+
   if (_conf->lockdep) {
     lockdep_unregister_ceph_context(this);
   }
@@ -371,6 +376,7 @@ CephContext::~CephContext()
 
   delete _conf;
   ceph_spin_destroy(&_service_thread_lock);
+  ceph_spin_destroy(&_associated_objs_lock);
 
   delete _crypto_none;
   delete _crypto_aes;
index ba6062032e7df177fabcf8ce04bd1bf144388cb5..e7b8b6c828eefa836f3d91ca471666bff868783a 100644 (file)
@@ -17,6 +17,8 @@
 
 #include <iostream>
 #include <stdint.h>
+#include <string>
+using namespace std;
 
 #include "include/buffer.h"
 #include "include/atomic.h"
@@ -58,6 +60,10 @@ private:
   ~CephContext();
   atomic_t nref;
 public:
+  class AssociatedSingletonObject {
+   public:
+    virtual ~AssociatedSingletonObject() {}
+  };
   CephContext *get() {
     nref.inc();
     return this;
@@ -102,6 +108,17 @@ public:
   void do_command(std::string command, cmdmap_t& cmdmap, std::string format,
                  bufferlist *out);
 
+  template<typename T>
+  void lookup_or_create_singleton_object(T*& p, const string &name) {
+    ceph_spin_lock(&_associated_objs_lock);
+    if (!_associated_objs.count(name)) {
+      p = new T(this);
+      _associated_objs[name] = reinterpret_cast<AssociatedSingletonObject*>(p);
+    } else {
+      p = reinterpret_cast<T*>(_associated_objs[name]);
+    }
+    ceph_spin_unlock(&_associated_objs_lock);
+  }
   /**
    * get a crypto handler
    */
@@ -138,6 +155,9 @@ private:
 
   ceph::HeartbeatMap *_heartbeat_map;
 
+  ceph_spinlock_t _associated_objs_lock;
+  map<string, AssociatedSingletonObject*> _associated_objs;
+
   // crypto
   CryptoNone *_crypto_none;
   CryptoAES *_crypto_aes;