You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123 lines
2.8 KiB
C

4 years ago
#pragma once
#include <mutex>
#include <atomic>
#include <shared_mutex>
#include <map>
template<class T>
class lp_multi_base
{
public:
class PTR {
public:
PTR(T* ptr) { ptr_ = ptr; }
~PTR() { if (ptr_) ptr_->mutex_lock_.unlock_shared(); }
bool valid() { return (ptr_) ? true : false; }
T* data() { return ptr_; }
T* operator->() { return ptr_; }
private:
T* ptr_{ nullptr };
};
protected:
static std::recursive_mutex s_inst_map_mutex_;
static std::map<std::string, T*> s_inst_map_;
std::string inst_name_;
std::shared_mutex mutex_lock_;
public:
lp_multi_base(const std::string& inst_name)
: inst_name_(inst_name)
{};
virtual ~lp_multi_base(void) {};
virtual void close() {};
static void create_instance(const std::string& inst_name)
{
std::lock_guard<std::recursive_mutex> locker(s_inst_map_mutex_);
if (inst_name.empty()) return;
typename std::map<std::string, T*>::iterator itr;
itr = s_inst_map_.find(inst_name);
if (itr == s_inst_map_.end()){
s_inst_map_[inst_name] = new T(inst_name);
}
};
static T* get_instance(const std::string& inst_name)
{
std::lock_guard<std::recursive_mutex> locker(s_inst_map_mutex_);
if (inst_name.empty()) return nullptr;
typename std::map<std::string, T*>::iterator itr;
itr = s_inst_map_.find(inst_name);
if (itr != s_inst_map_.end()){
itr->second->mutex_lock_.lock_shared();
return itr->second;
}
return nullptr;
};
static void uninstance(const std::string& inst_name)
{
std::lock_guard<std::recursive_mutex> locker(s_inst_map_mutex_);
if (inst_name.empty()) return;
typename std::map<std::string, T*>::iterator itr;
itr = s_inst_map_.find(inst_name);
if (itr != s_inst_map_.end()){
T* pptr = itr->second;
pptr->mutex_lock_.lock();
pptr->mutex_lock_.unlock();
s_inst_map_.erase(itr);
pptr->close();
}
};
//static void uninstance1(const std::string& inst_name)
//{
// std::lock_guard<std::recursive_mutex> locker(s_inst_map_mutex_);
// if (inst_name.empty()) return;
// typename std::map<std::string, T*>::iterator itr;
// itr = s_inst_map_.find(inst_name);
// while (itr != s_inst_map_.end()) {
// T* pptr = itr->second;
// pptr->mutex_lock_.lock();
// pptr->mutex_lock_.unlock();
// s_inst_map_.erase(itr);
// pptr->close();
// itr++;
// }
//};
static void uninstance_all()
{
std::lock_guard<std::recursive_mutex> locker(s_inst_map_mutex_);
typename std::map<std::string, T*>::iterator itr = s_inst_map_.begin();
for (; itr != s_inst_map_.end();)
{
T* pptr = itr->second;
pptr->mutex_lock_.lock();
pptr->mutex_lock_.unlock();
s_inst_map_.erase(itr++);
pptr->close();
}
};
};
template <class T>
std::map<std::string, T*> lp_multi_base<T>::s_inst_map_;
template <class T>
std::recursive_mutex lp_multi_base<T>::s_inst_map_mutex_;