mirror of
https://github.com/mapnik/mapnik.git
synced 2025-12-08 20:13:09 +00:00
1. register singleton destruction with std::atexit
2. allow connection pool to grow (up to max)
This commit is contained in:
parent
6ebe6dab07
commit
f4502df850
@ -68,25 +68,25 @@ namespace mapnik
|
||||
typedef std::deque<HolderType> ContType;
|
||||
|
||||
Creator<T> creator_;
|
||||
const int initialSize_;
|
||||
const int maxSize_;
|
||||
const unsigned initialSize_;
|
||||
const unsigned maxSize_;
|
||||
ContType usedPool_;
|
||||
ContType unusedPool_;
|
||||
boost::mutex mutex_;
|
||||
public:
|
||||
|
||||
Pool(const Creator<T>& creator,int initialSize=5,int maxSize=20)
|
||||
Pool(const Creator<T>& creator,unsigned initialSize=1, unsigned maxSize=10)
|
||||
:creator_(creator),
|
||||
initialSize_(initialSize),
|
||||
maxSize_(maxSize)
|
||||
{
|
||||
for (int i=0;i<initialSize_;++i)
|
||||
for (unsigned i=0; i < initialSize_; ++i)
|
||||
{
|
||||
unusedPool_.push_back(HolderType(creator_()));
|
||||
}
|
||||
}
|
||||
|
||||
const HolderType& borrowObject()
|
||||
HolderType borrowObject()
|
||||
{
|
||||
mutex::scoped_lock lock(mutex_);
|
||||
typename ContType::iterator itr=unusedPool_.begin();
|
||||
@ -99,11 +99,20 @@ namespace mapnik
|
||||
itr=unusedPool_.erase(itr);
|
||||
return usedPool_[usedPool_.size()-1];
|
||||
}
|
||||
static const HolderType defaultObj;
|
||||
return defaultObj;
|
||||
else if (unusedPool_.size() < maxSize_)
|
||||
{
|
||||
HolderType conn(creator_());
|
||||
usedPool_.push_back(conn);
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "create << " << conn.get() << "\n";
|
||||
#endif
|
||||
return conn;
|
||||
}
|
||||
|
||||
return HolderType();
|
||||
}
|
||||
|
||||
void returnObject(const HolderType& obj)
|
||||
void returnObject(HolderType obj)
|
||||
{
|
||||
mutex::scoped_lock lock(mutex_);
|
||||
typename ContType::iterator itr=usedPool_.begin();
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
#define UTILS_HPP
|
||||
// stl
|
||||
#include <stdexcept>
|
||||
#include <cstdlib>
|
||||
#include <limits>
|
||||
#include <ctime>
|
||||
#include <sstream>
|
||||
@ -66,18 +67,21 @@ namespace mapnik
|
||||
int Test::* pMember_;
|
||||
int (Test::*pMemberFn_)(int);
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
static T* create()
|
||||
{
|
||||
static MaxAlign staticMemory;
|
||||
return new(&staticMemory) T;
|
||||
}
|
||||
|
||||
static void destroy(volatile T* obj)
|
||||
{
|
||||
obj->~T();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename T,
|
||||
template <typename T> class CreatePolicy=CreateStatic> class singleton
|
||||
{
|
||||
@ -90,14 +94,20 @@ namespace mapnik
|
||||
{
|
||||
throw std::runtime_error("dead reference!");
|
||||
}
|
||||
|
||||
static void DestroySingleton()
|
||||
{
|
||||
CreatePolicy<T>::destroy(pInstance_);
|
||||
pInstance_ = 0;
|
||||
destroyed_=true;
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << " destroyed singleton \n";
|
||||
#endif
|
||||
}
|
||||
|
||||
protected:
|
||||
static mutex mutex_;
|
||||
singleton() {}
|
||||
virtual ~singleton()
|
||||
{
|
||||
CreatePolicy<T>::destroy(pInstance_);
|
||||
destroyed_=true;
|
||||
}
|
||||
public:
|
||||
static T* instance()
|
||||
{
|
||||
@ -113,6 +123,8 @@ namespace mapnik
|
||||
else
|
||||
{
|
||||
pInstance_=CreatePolicy<T>::create();
|
||||
// register destruction
|
||||
std::atexit(&DestroySingleton);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -126,72 +138,7 @@ namespace mapnik
|
||||
template <typename T> class CreatePolicy> T* singleton<T,CreatePolicy>::pInstance_=0;
|
||||
template <typename T,
|
||||
template <typename T> class CreatePolicy> bool singleton<T,CreatePolicy>::destroyed_=false;
|
||||
|
||||
template <class T> class Handle
|
||||
{
|
||||
T* ptr_;
|
||||
int* pCount_;
|
||||
public:
|
||||
T* operator->() {return ptr_;}
|
||||
const T* operator->() const {return ptr_;}
|
||||
Handle(T* ptr)
|
||||
:ptr_(ptr),pCount_(new int(1)) {}
|
||||
Handle(const Handle& rhs)
|
||||
:ptr_(rhs.ptr_),pCount_(rhs.pCount_)
|
||||
{
|
||||
(*pCount_)++;
|
||||
}
|
||||
Handle& operator=(const Handle& rhs)
|
||||
{
|
||||
if (ptr_==rhs.ptr_) return *this;
|
||||
if (--(*pCount_)==0)
|
||||
{
|
||||
delete ptr_;
|
||||
delete pCount_;
|
||||
}
|
||||
ptr_=rhs.ptr_;
|
||||
pCount_=rhs.pCount_;
|
||||
(*pCount_)++;
|
||||
return *this;
|
||||
}
|
||||
~Handle()
|
||||
{
|
||||
if (--(*pCount_)==0)
|
||||
{
|
||||
delete ptr_;
|
||||
delete pCount_;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//converters
|
||||
class BadConversion : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
BadConversion(const std::string& s)
|
||||
:std::runtime_error(s)
|
||||
{}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline std::string toString(const T& x)
|
||||
{
|
||||
std::ostringstream o;
|
||||
if (!(o << x))
|
||||
throw BadConversion(std::string("toString(")
|
||||
+ typeid(x).name() + ")");
|
||||
return o.str();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void fromString(const std::string& s, T& x,
|
||||
bool failIfLeftoverChars = true)
|
||||
{
|
||||
std::istringstream i(s);
|
||||
char c;
|
||||
if (!(i >> x) || (failIfLeftoverChars && i.get(c)))
|
||||
throw BadConversion("fromString("+s+")");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -89,6 +89,9 @@ public:
|
||||
~Connection()
|
||||
{
|
||||
PQfinish(conn_);
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::clog << "close connection " << conn_ << "\n";
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -76,7 +76,7 @@ class ConnectionManager : public singleton <ConnectionManager,CreateStatic>
|
||||
|
||||
public:
|
||||
|
||||
bool registerPool(const ConnectionCreator<Connection>& creator,int initialSize,int maxSize)
|
||||
bool registerPool(const ConnectionCreator<Connection>& creator,unsigned initialSize,unsigned maxSize)
|
||||
{
|
||||
mutex::scoped_lock lock(mutex_);
|
||||
if (pools_.find(creator.id())==pools_.end())
|
||||
@ -89,7 +89,7 @@ public:
|
||||
|
||||
}
|
||||
|
||||
const boost::shared_ptr<PoolType>& getPool(const std::string& key)
|
||||
boost::shared_ptr<PoolType> getPool(std::string const& key)
|
||||
{
|
||||
mutex::scoped_lock lock(mutex_);
|
||||
ContType::const_iterator itr=pools_.find(key);
|
||||
@ -101,7 +101,7 @@ public:
|
||||
return emptyPool;
|
||||
}
|
||||
|
||||
const HolderType& get(const std::string& key)
|
||||
HolderType get(std::string const& key)
|
||||
{
|
||||
mutex::scoped_lock lock(mutex_);
|
||||
ContType::const_iterator itr=pools_.find(key);
|
||||
@ -110,10 +110,9 @@ public:
|
||||
boost::shared_ptr<PoolType> pool=itr->second;
|
||||
return pool->borrowObject();
|
||||
}
|
||||
static const HolderType EmptyConn;
|
||||
return EmptyConn;
|
||||
return HolderType();
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
ConnectionManager() {}
|
||||
ConnectionManager(const ConnectionManager&);
|
||||
|
||||
@ -54,7 +54,7 @@ postgis_datasource::postgis_datasource(parameters const& params)
|
||||
params.get("password"))
|
||||
{
|
||||
ConnectionManager *mgr=ConnectionManager::instance();
|
||||
mgr->registerPool(creator_,10,20);
|
||||
mgr->registerPool(creator_,5,10);
|
||||
|
||||
shared_ptr<Pool<Connection,ConnectionCreator> > pool=mgr->getPool(creator_.id());
|
||||
if (pool)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user