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
00026
00027
00028 #ifndef _terimber_template_hpp_
00029 #define _terimber_template_hpp_
00030
00031 #include "base/template.h"
00032 #include "base/keymaker.hpp"
00033 #include "alg/algorith.hpp"
00034
00035 BEGIN_TERIMBER_NAMESPACE
00036 #pragma pack(4)
00037
00038
00039 template < class C >
00040 pool< C >::pool(C& creator, size_t pool_size) :
00041 _creator(creator), _locker(pool_size ? pool_size : 1), _busy_objects(256), _free_objects(256)
00042 {
00043 }
00044
00045 template < class C >
00046 pool< C >::~pool()
00047 {
00048 clear();
00049 }
00050
00051
00052 template < class C >
00053 inline
00054 TYPENAME pool< C >::TYPE*
00055 pool< C >::loan_object(const ARG& arg, size_t timeout)
00056 {
00057
00058 if (_locker.enter(timeout))
00059 {
00060 TYPE* obj = 0;
00061
00062 mutex_keeper guard(_mtx);
00063
00064 if (!_free_objects.empty())
00065 {
00066
00067 const pool_entry& x = _free_objects.front();
00068
00069 obj = x._obj;
00070
00071 _busy_objects.push_back(x);
00072
00073 _free_objects.pop_front();
00074 }
00075 else
00076 {
00077 if ((obj = _creator.create(arg)))
00078 {
00079 pool_entry entry(obj);
00080 _busy_objects.push_back(entry);
00081 }
00082 else
00083 {
00084 _locker.leave();
00085
00086 return 0;
00087 }
00088 }
00089
00090
00091 guard.unlock();
00092
00093 _creator.activate(obj, arg);
00094
00095 return obj;
00096 }
00097
00098
00099 return 0;
00100 }
00101
00102
00103 template < class C >
00104 inline
00105 void
00106 pool< C >::return_object(TYPE* obj, const ARG& arg)
00107 {
00108 if (!obj)
00109 return;
00110
00111
00112 mutex_keeper guard(_mtx);
00113
00114
00115 for (TYPENAME list_pool_entry_t::iterator it_busy = _busy_objects.begin(); it_busy != _busy_objects.end(); ++it_busy)
00116 {
00117 if (it_busy->_obj == obj)
00118 {
00119 date now;
00120 it_busy->_rest = now;
00121 _creator.back(obj, arg);
00122 _free_objects.push_front(*it_busy);
00123 _busy_objects.erase(it_busy);
00124 guard.unlock();
00125 _locker.leave();
00126 return;
00127 }
00128 }
00129
00130 assert(false);
00131 }
00132
00133
00134 template < class C >
00135 inline
00136 void
00137 pool< C >::clear(const ARG& arg)
00138 {
00139 keylocker_server keeper(_locker,
00140 #ifdef _DEBUG
00141 10000
00142 #else
00143 3000
00144 #endif
00145 );
00146
00147 assert(keeper);
00148
00149
00150 mutex_keeper guard(_mtx);
00151
00152 while (!_busy_objects.empty())
00153 {
00154 _creator.destroy(_busy_objects.front()._obj, arg);
00155 _busy_objects.pop_front();
00156 }
00157
00158 while (!_free_objects.empty())
00159 {
00160 _creator.destroy(_free_objects.front()._obj, arg);
00161 _free_objects.pop_front();
00162 }
00163 }
00164
00165
00166 template < class C >
00167 inline
00168 void
00169 pool< C >::deactivate(size_t maxrest, const ARG& arg)
00170 {
00171
00172 mutex_keeper guard(_mtx);
00173
00174 date now;
00175 sb8_t deadline = now;
00176 deadline -= maxrest;
00177
00178 for (TYPENAME list_pool_entry_t::iterator it_free = _free_objects.begin(); it_free != _free_objects.end(); ++it_free)
00179 {
00180 if (!it_free->_rest || it_free->_rest > deadline)
00181 continue;
00182
00183 it_free->_rest = 0;
00184 _creator.deactivate(it_free->_obj, arg);
00185 }
00186 }
00187
00188
00189 template < class C >
00190 inline
00191 void
00192 pool< C >::purge(size_t maxrest, const ARG& arg)
00193 {
00194
00195 mutex_keeper guard(_mtx);
00196
00197 date now;
00198 sb8_t deadline = now;
00199 deadline -= maxrest;
00200
00201 for (TYPENAME list_pool_entry_t::iterator it_free = _free_objects.begin(); it_free != _free_objects.end();)
00202 {
00203 if (it_free->_rest > deadline)
00204 ++it_free;
00205 else
00206 {
00207 _creator.destroy(it_free->_obj, arg);
00208 it_free = _free_objects.erase(it_free);
00209 }
00210 }
00211 }
00212
00213 template < class C >
00214 inline
00215 void
00216 pool< C >::get_stats(size_t& free_objects, size_t& busy_objects) const
00217 {
00218
00219 mutex_keeper guard(_mtx);
00220 free_objects = _free_objects.size();
00221 busy_objects = _busy_objects.size();
00222 }
00223
00225
00226
00227
00228
00229 template < class C >
00230 smart_pointer< C >::smart_pointer(C& crt, const ARG& n) :
00231 _crt(crt)
00232 {
00233 _ptr = crt.create(n);
00234 }
00235
00236
00237
00238 template < class C >
00239 smart_pointer< C >::smart_pointer(C& crt) :
00240 _crt(crt), _ptr(0)
00241 {
00242 }
00243
00244
00245 template < class C >
00246 smart_pointer< C >::~smart_pointer()
00247 {
00248 clear();
00249 }
00250
00251
00252 template < class C >
00253 inline
00254 smart_pointer< C >&
00255 smart_pointer< C >::operator=(const TYPE* x)
00256 {
00257 clear();
00258 _ptr = (TYPENAME smart_pointer< C >::TYPE*)x;
00259 return *this;
00260 }
00261
00262 template < class C >
00263 inline
00264 TYPENAME smart_pointer< C >::TYPE*
00265 smart_pointer< C >::operator->()
00266 {
00267 return _ptr;
00268 }
00269
00270 template < class C >
00271 inline
00272 const TYPENAME smart_pointer< C >::TYPE*
00273 smart_pointer< C >::operator->() const
00274 {
00275 return _ptr;
00276 }
00277
00278
00279
00280 template < class C >
00281 inline
00282 TYPENAME smart_pointer< C >::TYPE**
00283 smart_pointer< C >::operator&()
00284 {
00285 return &_ptr;
00286 }
00287
00288
00289 template < class C >
00290 inline
00291 bool
00292 smart_pointer< C >::operator!() const
00293 {
00294 return !_ptr;
00295 }
00296
00297
00298 template < class C >
00299 inline
00300 void
00301 smart_pointer< C >::clear()
00302 {
00303 if (_ptr)
00304 {
00305 _crt.destroy(_ptr);
00306 _ptr = 0;
00307 }
00308 }
00309
00310 template < class C >
00311 inline
00312 TYPENAME smart_pointer< C >::TYPE*
00313 smart_pointer< C >::detach()
00314 {
00315 TYPENAME smart_pointer< C >::TYPE* ptr = _ptr;
00316 _ptr = 0;
00317 return ptr;
00318 }
00319
00320
00321 template < class C >
00322 inline
00323 void
00324 smart_pointer< C >::attach(TYPE* obj, bool free)
00325 {
00326 free ? clear() : detach(); _ptr = obj;
00327 }
00328
00330 template < class P >
00331 pool_object_keeper< P >::pool_object_keeper(P* pool_, TYPE* obj) :
00332 _pool(pool_), _obj(obj)
00333 {
00334 }
00335
00336 template < class P >
00337 pool_object_keeper< P >::pool_object_keeper(P* pool_, const ARG& arg, size_t timeout) :
00338 _pool(pool_)
00339 {
00340 _obj = _pool ? _pool->loan_object(arg, timeout) : 0;
00341 }
00342
00343 template < class P >
00344 pool_object_keeper< P >::~pool_object_keeper()
00345 {
00346 if (_pool && _obj)
00347 _pool->return_object(_obj);
00348 }
00349
00350 template < class P >
00351 inline
00352 TYPENAME pool_object_keeper< P >::TYPE*
00353 pool_object_keeper< P >::operator->()
00354 {
00355 return _obj;
00356 }
00357
00358 template < class P >
00359 inline
00360 const TYPENAME pool_object_keeper< P >::TYPE*
00361 pool_object_keeper< P >::operator->() const
00362 {
00363 return _obj;
00364 }
00365
00366 template < class P >
00367 inline
00368 bool
00369 pool_object_keeper< P >::operator!() const
00370 {
00371 return !_obj;
00372 }
00373
00374
00375 #pragma pack()
00376 END_TERIMBER_NAMESPACE
00377
00378 #endif // _terimber_template_hpp_
00379