|
@@ -1,6 +1,7 @@
|
|
|
#ifndef _WRITE_COPY_HPP_
|
|
|
#define _WRITE_COPY_HPP_
|
|
|
//add之前如果有数据,需要把运行中更改的数据进行保存。
|
|
|
+#include <assert.h>
|
|
|
#include <unordered_map>
|
|
|
#include <algorithm>
|
|
|
#include <memory>
|
|
@@ -115,54 +116,108 @@ private:
|
|
|
}
|
|
|
};
|
|
|
|
|
|
+template<typename T>
|
|
|
+struct safe_shared_ptr
|
|
|
+{
|
|
|
+ std::atomic<int> m_mutex;
|
|
|
+ std::shared_ptr<T> m_ptr;
|
|
|
+
|
|
|
+ safe_shared_ptr(std::shared_ptr<T> ptr)
|
|
|
+ {
|
|
|
+ m_mutex=0;
|
|
|
+ m_ptr=ptr;
|
|
|
+ }
|
|
|
+
|
|
|
+ safe_shared_ptr(safe_shared_ptr<T>&&ptr)
|
|
|
+ {
|
|
|
+ m_mutex.store(ptr.m_mutex.load());
|
|
|
+ m_ptr=std::move(ptr.get());
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ bool set(std::shared_ptr<T> ptr)
|
|
|
+ {
|
|
|
+ lock();
|
|
|
+ m_ptr=ptr;
|
|
|
+ unlock();
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ std::shared_ptr<T> get()
|
|
|
+ {
|
|
|
+ lock();
|
|
|
+ std::shared_ptr<T> ret=m_ptr;
|
|
|
+ unlock();
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+private:
|
|
|
+ void lock()
|
|
|
+ {
|
|
|
+ int expected=0;
|
|
|
+ while(!m_mutex.compare_exchange_strong(expected,1))
|
|
|
+ expected=0;
|
|
|
+ assert(m_mutex.load()==1);
|
|
|
+ }
|
|
|
+
|
|
|
+ void unlock()
|
|
|
+ {
|
|
|
+ m_mutex.store(0);
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
template<typename T,typename K,typename V>
|
|
|
struct single_base:write_copy_base<T,K,V>
|
|
|
{
|
|
|
typedef write_copy_base<T,K,V> base;
|
|
|
- static std::shared_ptr<T> m_instance;
|
|
|
+
|
|
|
+ static safe_shared_ptr<T> m_instance;
|
|
|
+ std::mutex m_mutex;
|
|
|
+
|
|
|
static std::shared_ptr<T> instance()
|
|
|
{
|
|
|
- return m_instance;
|
|
|
+ return m_instance.get();
|
|
|
}
|
|
|
|
|
|
- std::mutex m_mutex;
|
|
|
-
|
|
|
void add(K k,V c)
|
|
|
{
|
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
|
|
- m_instance=std::move(base::clone_add(k,c));
|
|
|
+ m_instance.set(base::clone_add(k,c));
|
|
|
}
|
|
|
|
|
|
void add(const std::unordered_map<K,V>&c)
|
|
|
{
|
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
|
|
- m_instance=std::move(base::clone_add(c));
|
|
|
+ m_instance.set(base::clone_add(c));
|
|
|
}
|
|
|
void remove(K k,V c)
|
|
|
{
|
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
|
|
- m_instance=std::move(base::clone_remove(k,c));
|
|
|
+ m_instance.set(base::clone_remove(k,c));
|
|
|
}
|
|
|
|
|
|
void remove(const std::unordered_map<K,V>&c)
|
|
|
{
|
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
|
|
- m_instance=std::move(base::clone_remove(c));
|
|
|
+ m_instance.set(base::clone_remove(c));
|
|
|
}
|
|
|
|
|
|
void remove(const std::vector<K>&list)
|
|
|
{
|
|
|
- std::lock_guard<std::mutex> lock(m_mutex);
|
|
|
- m_instance=std::move(base::clone_remove(list));
|
|
|
+ std::lock_guard<std::mutex> lock(m_mutex);
|
|
|
+ m_instance.set(base::clone_remove(list));
|
|
|
}
|
|
|
|
|
|
void remove(K k)
|
|
|
{
|
|
|
- std::lock_guard<std::mutex> lock(m_mutex);
|
|
|
- m_instance=std::move(base::clone_remove(k));
|
|
|
+ std::lock_guard<std::mutex> lock(m_mutex);
|
|
|
+ m_instance.set(base::clone_remove(k));
|
|
|
}
|
|
|
};
|
|
|
|
|
|
+template<typename T,typename K,typename V> safe_shared_ptr<T> single_base<T,K,V>::m_instance=std::make_shared<T>();
|
|
|
+
|
|
|
#endif
|
|
|
|
|
|
|