00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef POOL_HPP
00026 #define POOL_HPP
00027
00028
00029 #include <iostream>
00030 #include <map>
00031 #include <deque>
00032 #include <ctime>
00033
00034 #include <boost/shared_ptr.hpp>
00035 #include <boost/thread/mutex.hpp>
00036 #include <boost/utility.hpp>
00037
00038 #include <mapnik/utils.hpp>
00039
00040 namespace mapnik
00041 {
00042 template <typename T, typename PoolT>
00043 class PoolGuard
00044 {
00045 private:
00046 const T& obj_;
00047 PoolT& pool_;
00048 public:
00049 explicit PoolGuard(const T& ptr,PoolT& pool)
00050 : obj_(ptr),
00051 pool_(pool) {}
00052
00053 ~PoolGuard()
00054 {
00055 pool_->returnObject(obj_);
00056 }
00057
00058 private:
00059 PoolGuard();
00060 PoolGuard(const PoolGuard&);
00061 PoolGuard& operator=(const PoolGuard&);
00062 };
00063
00064 template <typename T,template <typename> class Creator>
00065 class Pool : private boost::noncopyable
00066 {
00067 typedef boost::shared_ptr<T> HolderType;
00068 typedef std::deque<HolderType> ContType;
00069
00070 Creator<T> creator_;
00071 const unsigned initialSize_;
00072 const unsigned maxSize_;
00073 ContType usedPool_;
00074 ContType unusedPool_;
00075 boost::mutex mutex_;
00076 public:
00077
00078 Pool(const Creator<T>& creator,unsigned initialSize=1, unsigned maxSize=10)
00079 :creator_(creator),
00080 initialSize_(initialSize),
00081 maxSize_(maxSize)
00082 {
00083 for (unsigned i=0; i < initialSize_; ++i)
00084 {
00085 HolderType conn(creator_());
00086 if (conn->isOK())
00087 unusedPool_.push_back(conn);
00088 }
00089 }
00090
00091 HolderType borrowObject()
00092 {
00093 mutex::scoped_lock lock(mutex_);
00094 typename ContType::iterator itr=unusedPool_.begin();
00095 if (itr!=unusedPool_.end())
00096 {
00097 #ifdef MAPNIK_DEBUG
00098 std::clog<<"borrow "<<(*itr).get()<<"\n";
00099 #endif
00100 usedPool_.push_back(*itr);
00101 itr=unusedPool_.erase(itr);
00102 return usedPool_[usedPool_.size()-1];
00103 }
00104 else if (unusedPool_.size() < maxSize_)
00105 {
00106 HolderType conn(creator_());
00107 if (conn->isOK())
00108 {
00109 usedPool_.push_back(conn);
00110 #ifdef MAPNIK_DEBUG
00111 std::clog << "create << " << conn.get() << "\n";
00112 #endif
00113 return conn;
00114 }
00115 }
00116 return HolderType();
00117 }
00118
00119 void returnObject(HolderType obj)
00120 {
00121 mutex::scoped_lock lock(mutex_);
00122 typename ContType::iterator itr=usedPool_.begin();
00123 while (itr != usedPool_.end())
00124 {
00125 if (obj.get()==(*itr).get())
00126 {
00127 #ifdef MAPNIK_DEBUG
00128 std::clog<<"return "<<(*itr).get()<<"\n";
00129 #endif
00130 unusedPool_.push_back(*itr);
00131 usedPool_.erase(itr);
00132 return;
00133 }
00134 ++itr;
00135 }
00136 }
00137 };
00138 }
00139 #endif //POOL_HPP