bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
RCObject.h
1
2// 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
40namespace agg_util {
41class RCOBjectPool;
42class RCObject;
43
44typedef std::set<RCObject*> RCObjectSet;
45
58 friend class RCObject;
59
60public:
63
65 virtual ~RCObjectPool();
66
70 bool contains(RCObject* pObj) const;
71
76 void add(RCObject* pObj);
77
80 void remove(RCObject* pObj)
81 {
82 release(pObj, false);
83 }
84
91 void release(RCObject* pObj, bool shouldDelete = true);
92
93protected:
98
99private:
100
101 // A set of the live, monitored objects.
102 // Lookups are log(N) and entries unique, as required.
103 // All entries in this list will be delete'd in the dtor.
104 RCObjectSet _liveObjects;
105};
106// class RCObjectPool
107
113class UseCountHitZeroCB {
114public:
115 UseCountHitZeroCB()
116 {
117 }
118 virtual ~UseCountHitZeroCB()
119 {
120 }
121 virtual void executeUseCountHitZeroCB(RCObject* pAboutToDie) = 0;
122};
123
164class RCObject: public virtual RCObjectInterface // abstract interface
165{
166 friend class RCObjectPool;
167
168 typedef std::list<UseCountHitZeroCB*> PreDeleteCBList;
169
170private:
171 RCObject& operator=(const RCObject& rhs); //disallow
172
173public:
174
178 RCObject(RCObjectPool* pool = 0);
179
183 RCObject(const RCObject& proto);
184
185 virtual ~RCObject();
186
189 virtual int ref() const;
190
201 virtual int unref() const;
202
204 virtual int getRefCount() const;
205
212 virtual void removeFromPool() const;
213
215 virtual std::string toString() const;
216
217public:
218 // to workaround template friend issues. Not designed for public consumption.
219
222
225
226private:
227 // interface
228
230 std::string printRCObject() const;
231
242 void executeAndClearPreDeleteCallbacks();
243
244private:
245 // data rep
246
247 // The reference count... mutable since we want to ref count const objects as well,
248 // and the count doesn't affect the semantic constness of the subclasses.
249 mutable int _count;
250
251 // If not null, the object is from the given pool and should be release()'d to the
252 // pool when count hits 0, not deleted. If null, it can be deleted.
253 RCObjectPool* _pool;
254
255 // Callback list for when the use count hits 0 but before deallocate
256 PreDeleteCBList _preDeleteCallbacks;
257
258};
259// class RCObject
260
283template<class T>
284class RCPtr {
285public:
286 RCPtr(T* pRef = 0) :
287 _obj(pRef)
288 {
289 init();
290 }
291
292 RCPtr(const RCPtr& from) :
293 _obj(from._obj)
294 {
295 init();
296 }
297
298 ~RCPtr()
299 {
300 if (_obj) {
301 _obj->unref();
302 _obj = 0;
303 }
304 }
305
306 RCPtr&
307 operator=(const RCPtr& rhs)
308 {
309 if (rhs._obj != _obj) {
310 RCObject* oldObj = _obj;
311 _obj = rhs._obj;
312 init();
313 if (oldObj) {
314 oldObj->unref();
315 }
316 }
317 return *this;
318 }
319
320 T&
321 operator*() const
322 {
323 // caller is on their own if they deref this as null,
324 // so should check with get() first.
325 return *_obj;
326 }
327
328 T*
329 operator->() const
330 {
331 return _obj;
332 }
333
334 T*
335 get() const
336 {
337 return _obj;
338 }
339
352 T*
353 refAndGet() const
354 {
355 if (_obj) {
356 _obj->ref();
357 }
358 return _obj;
359 }
360
361private:
362 void init()
363 {
364 if (_obj) {
365 _obj->ref();
366 }
367 }
368
369private:
370 T* _obj;
371};
372// class RCPtr<T>
373
375class BadWeakPtr: public std::runtime_error {
376public:
377 BadWeakPtr(const std::string& msg) :
378 std::runtime_error(msg)
379 {
380 }
381
382 virtual ~BadWeakPtr() noexcept
383 {
384 }
385};
386// class BadWeakPtr
387
411template<class T>
412class WeakRCPtr: public UseCountHitZeroCB // can we private inherit this to avoid outside callers?
413{
414
415public:
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
430 ~WeakRCPtr()
431 {
432 clear();
433 }
434
435 WeakRCPtr& operator=(const WeakRCPtr& r)
436 {
437 if (&r != this) {
438 clear();
439 _pObj = r._pObj;
440 addMeAsListener();
441 }
442 return *this;
443 }
444
446 bool expired() const
447 {
448 return empty();
449 }
450
452 bool empty() const
453 {
454 return (!_pObj);
455 }
456
457 RCPtr<T> lock() const
458 {
459 // return a safe shared ptr to the wrapped resource
460 // which will up it's count properly
461 if (_pObj) {
462 return RCPtr<T>(_pObj);
463 }
464 else {
465 return RCPtr<T>(NULL);
466 }
467 }
468
472 void clear()
473 {
474 // Remove the listener, clear the ptr so it's like default ctor.
475 removeMeAsListener();
476 _pObj = NULL;
477 }
478
479public:
480 // to avoid template friend issues, but not for public use!
481
487 virtual void executeUseCountHitZeroCB(RCObject* pAboutToDie)
488 {
489 if (pAboutToDie != _pObj) {
490 throw BadWeakPtr("executeUseCountHitZeroCB() called with mismatched raw pointers!");
491 }
492 clear();
493 }
494
496private:
497
498 void removeMeAsListener()
499 {
500 if (_pObj) {
501 _pObj->removePreDeleteCB(this);
502 }
503 }
504
505 void addMeAsListener()
506 {
507 if (_pObj) {
508 _pObj->addPreDeleteCB(this);
509 }
510 }
511
512private:
513 // data rep
514
515 // The underlying wrapped object, or NULL if uninit or expired.
516 // NOTE: MUST be a subclass of RCObject
517 T* _pObj;
518
519};
520// class WeakRCPtr<T>
521
522}// namespace agg_util
523
524#endif /* __AGG_UTIL__REF_COUNTED_OBJECT_H__ */
A reference to an RCObject which automatically ref() and deref() on creation and destruction.
Definition RCObject.h:284
bool contains(RCObject *pObj) const
void release(RCObject *pObj, bool shouldDelete=true)
void remove(RCObject *pObj)
Definition RCObject.h:80
void add(RCObject *pObj)
A base class for a simple reference counted object.
Definition RCObject.h:165
RCObject(RCObjectPool *pool=0)
virtual int ref() const
virtual int getRefCount() const
virtual std::string toString() const
void removePreDeleteCB(UseCountHitZeroCB *pCB)
void addPreDeleteCB(UseCountHitZeroCB *pCB)
RCObject(const RCObject &proto)
virtual int unref() const
virtual void removeFromPool() const
A reference to an RCObject which automatically ref() and deref() on creation and destruction.
Definition RCObject.h:284
T * refAndGet() const
Definition RCObject.h:353
virtual void executeUseCountHitZeroCB(RCObject *pAboutToDie)
Definition RCObject.h:487
bool empty() const
Definition RCObject.h:452
bool expired() const
Definition RCObject.h:446
Helper class for temporarily hijacking an existing dhi to load a DDX response for one particular file...