OPeNDAP Hyrax Back End Server (BES)  Updated for version 3.8.3
RCObject.h
Go to the documentation of this file.
1 // This file is part of the "NcML Module" project, a BES module designed
3 // to allow NcML files to be used to be used as a wrapper to add
4 // AIS to existing datasets of any format.
5 //
6 // Copyright (c) 2009 OPeNDAP, Inc.
7 // Author: Michael Johnson <m.johnson@opendap.org>
8 //
9 // For more information, please also see the main website: http://opendap.org/
10 //
11 // This library is free software; you can redistribute it and/or
12 // modify it under the terms of the GNU Lesser General Public
13 // License as published by the Free Software Foundation; either
14 // version 2.1 of the License, or (at your option) any later version.
15 //
16 // This library is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 // Lesser General Public License for more details.
20 //
21 // You should have received a copy of the GNU Lesser General Public
22 // License along with this library; if not, write to the Free Software
23 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 //
25 // Please see the files COPYING and COPYRIGHT for more information on the GLPL.
26 //
27 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
29 #ifndef __AGG_UTIL__REF_COUNTED_OBJECT_H__
30 #define __AGG_UTIL__REF_COUNTED_OBJECT_H__
31 
32 #include "RCObjectInterface.h" // interface super
33 
34 #include <list>
35 #include <set>
36 #include <stdexcept>
37 #include <string>
38 #include <vector>
39 
40 namespace agg_util
41 {
42  class RCOBjectPool;
43  class RCObject;
44 
45  typedef std::set<RCObject*> RCObjectSet;
46 
59  {
60  friend class RCObject;
61 
62 public:
64  RCObjectPool();
65 
67  virtual ~RCObjectPool();
68 
72  bool contains(RCObject* pObj) const;
73 
78  void add(RCObject* pObj);
79 
82  void remove(RCObject* pObj)
83  {
84  release(pObj, false);
85  }
86 
93  void release(RCObject* pObj, bool shouldDelete=true);
94 
95 protected:
99  void deleteAllObjects();
100 
101 private:
102 
103  // A set of the live, monitored objects.
104  // Lookups are log(N) and entries unique, as required.
105  // All entries in this list will be delete'd in the dtor.
106  RCObjectSet _liveObjects;
107  }; // class RCObjectPool
108 
115  {
116  public:
118  virtual ~UseCountHitZeroCB() { }
119  virtual void executeUseCountHitZeroCB(RCObject* pAboutToDie) = 0;
120  };
121 
162  class RCObject
163  : public virtual RCObjectInterface // abstract interface
164  {
165  friend class RCObjectPool;
166 
167  typedef std::list<UseCountHitZeroCB*> PreDeleteCBList;
168 
169  private:
170  RCObject& operator=(const RCObject& rhs); //disallow
171 
172  public:
173 
177  RCObject(RCObjectPool* pool=0);
178 
182  RCObject(const RCObject& proto);
183 
184  virtual ~RCObject();
185 
188  virtual int ref() const;
189 
200  virtual int unref() const throw();
201 
203  virtual int getRefCount() const;
204 
211  virtual void removeFromPool() const;
212 
214  virtual std::string toString() const;
215 
216  public: // to workaround template friend issues. Not designed for public consumption.
217 
220 
223 
224  private: // interface
225 
227  std::string printRCObject() const;
228 
239  void executeAndClearPreDeleteCallbacks();
240 
241  private: // data rep
242 
243  // The reference count... mutable since we want to ref count const objects as well,
244  // and the count doesn't affect the semantic constness of the subclasses.
245  mutable int _count;
246 
247  // If not null, the object is from the given pool and should be release()'d to the
248  // pool when count hits 0, not deleted. If null, it can be deleted.
249  RCObjectPool* _pool;
250 
251  // Callback list for when the use count hits 0 but before deallocate
252  PreDeleteCBList _preDeleteCallbacks;
253 
254  }; // class RCObject
255 
278  template <class T>
279  class RCPtr
280  {
281  public:
282  RCPtr(T* pRef = 0)
283  : _obj(pRef)
284  {
285  init();
286  }
287 
288  RCPtr(const RCPtr& from)
289  : _obj(from._obj)
290  {
291  init();
292  }
293 
295  {
296  if (_obj)
297  {
298  _obj->unref();
299  _obj = 0;
300  }
301  }
302 
303  RCPtr&
304  operator=(const RCPtr& rhs)
305  {
306  if (rhs._obj != _obj)
307  {
308  RCObject* oldObj = _obj;
309  _obj = rhs._obj;
310  init();
311  if (oldObj)
312  {
313  oldObj->unref();
314  }
315  }
316  return *this;
317  }
318 
319  T&
320  operator*() const
321  {
322  // caller is on their own if they deref this as null,
323  // so should check with get() first.
324  return *_obj;
325  }
326 
327  T*
328  operator->() const
329  {
330  return _obj;
331  }
332 
333  T*
334  get() const
335  {
336  return _obj;
337  }
338 
351  T*
352  refAndGet() const
353  {
354  if (_obj)
355  {
356  _obj->ref();
357  }
358  return _obj;
359  }
360 
361  private:
362  void init()
363  {
364  if (_obj)
365  {
366  _obj->ref();
367  }
368  }
369 
370  private:
371  T* _obj;
372  }; // class RCPtr<T>
373 
374 
376  class BadWeakPtr : public std::runtime_error
377  {
378  public:
379  BadWeakPtr(const std::string& msg)
380  : std::runtime_error(msg)
381  {
382  }
383 
384  virtual ~BadWeakPtr() throw() { }
385  }; // class BadWeakPtr
386 
387 
411  template <class T>
412  class WeakRCPtr : public UseCountHitZeroCB // can we private inherit this to avoid outside callers?
413  {
414 
415  public:
416 
419  : _pObj(0)
420  {
421  }
422 
423  explicit WeakRCPtr(RCPtr<T> src)
424  {
425  // Connect to the shared ptr by adding listener and storing raw.
426  _pObj = src.get();
427  addMeAsListener();
428  }
429 
431  {
432  clear();
433  }
434 
436  {
437  if (&r != this)
438  {
439  clear();
440  _pObj = r._pObj;
441  addMeAsListener();
442  }
443  return *this;
444  }
445 
447  bool expired() const
448  {
449  return empty();
450  }
451 
453  bool empty() const
454  {
455  return (!_pObj);
456  }
457 
458  RCPtr<T> lock() const
459  {
460  // return a safe shared ptr to the wrapped resource
461  // which will up it's count properly
462  if (_pObj)
463  {
464  return RCPtr<T>(_pObj);
465  }
466  else
467  {
468  return RCPtr<T>(NULL);
469  }
470  }
471 
475  void clear()
476  {
477  // Remove the listener, clear the ptr so it's like default ctor.
478  removeMeAsListener();
479  _pObj = NULL;
480  }
481 
482  public: // to avoid template friend issues, but not for public use!
483 
489  virtual void executeUseCountHitZeroCB(RCObject* pAboutToDie)
490  {
491  if (pAboutToDie != _pObj)
492  {
493  throw BadWeakPtr(
494  "executeUseCountHitZeroCB() called with mismatched raw pointers!");
495  }
496  clear();
497  }
498 
499 
501  private:
502 
503  void removeMeAsListener()
504  {
505  if (_pObj)
506  {
507  _pObj->removePreDeleteCB(this);
508  }
509  }
510 
511  void addMeAsListener()
512  {
513  if (_pObj)
514  {
515  _pObj->addPreDeleteCB(this);
516  }
517  }
518 
519  private: // data rep
520 
521  // The underlying wrapped object, or NULL if uninit or expired.
522  // NOTE: MUST be a subclass of RCObject
523  T* _pObj;
524 
525  }; // class WeakRCPtr<T>
526 
527 } // namespace agg_util
528 
529 #endif /* __AGG_UTIL__REF_COUNTED_OBJECT_H__ */
Exception class for all errors from WeakRCPtr
Definition: RCObject.h:376
T * operator->() const
Definition: RCObject.h:328
T & operator*() const
Definition: RCObject.h:320
WeakRCPtr(RCPtr< T > src)
Definition: RCObject.h:423
virtual std::string toString() const
Just prints the count and address.
Definition: RCObject.cc:128
RCObjectPool()
Create an empty pool.
Definition: RCObject.cc:199
std::set< RCObject * > RCObjectSet
Definition: RCObject.h:43
void addPreDeleteCB(UseCountHitZeroCB *pCB)
Add uniquely.
Definition: RCObject.cc:145
bool empty() const
Will getting a lock() return a null?
Definition: RCObject.h:453
virtual ~RCObject()
Definition: RCObject.cc:63
virtual int unref() const
Decrease the reference count by one.
Definition: RCObject.cc:82
STL namespace.
void deleteAllObjects()
Call delete on all objects remaining in _liveObjects and clear it out.
Definition: RCObject.cc:258
A monitoring "pool" class for created RCObject's which allows us to forcibly delete any RCOBject's re...
Definition: RCObject.h:58
Helper class for temporarily hijacking an existing dhi to load a DDX response for one particular file...
virtual ~BadWeakPtr()
Definition: RCObject.h:384
T * refAndGet() const
If not null, ref() the object and then return it.
Definition: RCObject.h:352
RCPtr(const RCPtr &from)
Definition: RCObject.h:288
RCObject(RCObjectPool *pool=0)
If the pool is given, the object will be released back to the pool when its count hits 0...
Definition: RCObject.cc:39
WeakRCPtr()
Default contains NULL.
Definition: RCObject.h:418
virtual void executeUseCountHitZeroCB(RCObject *pAboutToDie)
Listener callback from the RCObject to implement the interface.
Definition: RCObject.h:489
RCPtr< T > lock() const
Definition: RCObject.h:458
void removePreDeleteCB(UseCountHitZeroCB *pCB)
Remove it exists.
Definition: RCObject.cc:164
#define NULL
Definition: wcsUtil.h:65
virtual int ref() const
Increase the reference count by one.
Definition: RCObject.cc:74
A reference to an RCObject which automatically ref() and deref() on creation and destruction.
Definition: RCObject.h:279
void release(RCObject *pObj, bool shouldDelete=true)
Tell the pool that the object's count is 0 and it can be released to be deleted or potentially reused...
Definition: RCObject.cc:228
CURL * init(char *error_buffer)
Get's a new instance of CURL* and performs basic configuration of that instance.
Definition: curl_utils.cc:426
A base class for a simple reference counted object.
Definition: RCObject.h:162
BadWeakPtr(const std::string &msg)
Definition: RCObject.h:379
Interface for registering callbacks to the RCObject for when the usecount hits 0 but before the deall...
Definition: RCObject.h:114
bool contains(RCObject *pObj) const
Definition: RCObject.cc:210
virtual ~RCObjectPool()
Forcibly delete all remaining objects in pool, regardless of ref count.
Definition: RCObject.cc:204
virtual int getRefCount() const
Get the current reference count.
Definition: RCObject.cc:110
bool expired() const
Will getting a lock() return a null?
Definition: RCObject.h:447
virtual void executeUseCountHitZeroCB(RCObject *pAboutToDie)=0
RCPtr(T *pRef=0)
Definition: RCObject.h:282
A variant of boost::weak_ptr that uses our intrusive RCObject counting.
Definition: RCObject.h:412
WeakRCPtr & operator=(const WeakRCPtr &r)
Definition: RCObject.h:435
T * get() const
Definition: RCObject.h:334
void clear()
Remove any listener and NULL the wrapped pointer.
Definition: RCObject.h:475
RCPtr & operator=(const RCPtr &rhs)
Definition: RCObject.h:304
void add(RCObject *pObj)
Add the object to the pool uniquely.
Definition: RCObject.cc:217
Interface class for a reference counted object.
virtual void removeFromPool() const
If the object is in an auto-delete pool, remove it from the pool and force it to only delete when it'...
Definition: RCObject.cc:116