00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef RESOURCEPOOL_RESOURCEPOOL_HH
00025 #define RESOURCEPOOL_RESOURCEPOOL_HH
00026
00027 #ifndef INCLUDED_GC_PTR_HH
00028 #include "mm/gc_ptr.hh"
00029 #endif
00030
00031 #ifndef MM_REFWRAP_HH
00032 #include "mm/RefWrap.hh"
00033 #endif
00034
00035 #ifndef RESOURCEPOOL_RESOURCEPOOLOPTIONS_HH
00036 #include "ResourcePoolOptions.hh"
00037 #endif
00038 #include "ResourcePoolInterface.hh"
00039
00040 #ifndef INCLUDED_THREAD_LOCK_HH
00041 #include "Thread/Lock.hh"
00042 #endif
00043
00044 #ifndef INCLUDED_THREAD_SYNCHRONIZE_HH
00045 #include "Thread/Synchronize.hh"
00046 #endif
00047
00048 #ifndef INCLUDED_CONDVAR_H
00049 #include "Thread/CondVar.hh"
00050 #endif
00051
00052 #ifndef RESOURCEPOOL_CREATEEXCEPTION_HH
00053 #include "CreateException.hh"
00054 #endif
00055
00056 #include "ResourcePoolType.hh"
00057 #include "ResourcePoolStats.hh"
00058 #include "ResourcePoolEventObserver.hh"
00059
00060
00061 #include <deque>
00062 #include <set>
00063 #include <map>
00064
00071 namespace fatalmind {
00072
00073 template<class T> class Command;
00074
00088 template<class Type>
00089 class ResourcePool: public ResourcePoolInterface<Type> {
00090 public:
00099 ResourcePool(const typename Type::factory_t&
00100 , const ResourcePoolOptions& o = ResourcePoolOptions::defaultOptions
00101 );
00102
00106 virtual ~ResourcePool();
00107
00108 virtual typename Type::resource_t& get();
00109 virtual bool free(typename Type::resource_t&);
00110 virtual bool fail(typename Type::resource_t&);
00111
00115 virtual void downsize();
00116
00117 ResourcePoolStats getStats() const;
00118
00122 typedef Type PoolType;
00123
00127 typedef typename Type::factory_t Factory;
00128
00134 inline const Factory& getFactory() const {
00135 return _factory;
00136 };
00137
00138
00142 inline ResourcePoolEventObserver::event_t setLogEvents(ResourcePoolEventObserver::event_t events) {
00143 return observer->setLogEvents(events);
00144 }
00145
00146 virtual void execute(Command<Type>&);
00147
00148 protected:
00149
00150 typedef typename Type::ThreadingModell TM;
00151 typedef typename TM::FastCondVar condvar_t;
00152 typedef Synchronize<condvar_t> sync_t;
00153
00154 typedef gc_ptr<typename Type::resource_t, TM> resource_ptr;
00155 typedef std::deque<resource_ptr> freePool_t;
00156
00157 typedef RefWrap<typename Type::resource_t> plainresource_ptr;
00158 typedef std::map<plainresource_ptr, resource_ptr> usedPool_t;
00159
00160 private:
00161
00162 const typename Type::factory_t _factory;
00163 const ResourcePoolOptions _options;
00164
00165 freePool_t _freePool;
00166 usedPool_t _usedPool;
00167
00168 mutable condvar_t _condvar;
00169
00170 bool _stopped;
00171
00172 ResourcePoolStats _stats;
00173
00174 const gc_ptr<ResourcePoolEventObserver> observer;
00175
00176 public:
00192 typedef typename Type::command_t Commands;
00193
00194 protected:
00195
00196 void sleepit(int tryno) const;
00197 typename Type::resource_t* moveToUsed();
00198
00199
00200 virtual const ResourcePoolOptions& getOptions() {
00201 return _options;
00202 };
00203
00204
00205 inline void _downsize();
00206 inline void _inc_pool();
00207
00208 void _waitForFree(const CreateException&, const SingleThreadedModel<>::Type);
00209 void _waitForFree(const CreateException&, const MultiThreadedModel<>::Type);
00210
00211 friend
00212 class fatalmind::Command<Type>;
00213
00214
00215 private:
00216
00217 ResourcePool(const ResourcePool<Type>&);
00218 ResourcePool<Type>& operator=(const ResourcePool<Type>&);
00219
00220 inline void event(int event, const std::string& resourceID = ResourcePoolEventObserver::NoResourceID, const std::string& message = "N/A") {
00221 observer->event(event, resourceID, message);
00222 }
00223 };
00224
00225
00226 }
00227 #endif