76 #ifndef _util_ref_ref_h
77 #define _util_ref_ref_h
83 #include <util/ref/identity.h>
90 #ifndef REF_CHECK_STACK
91 # define REF_CHECK_STACK 0
96 #ifndef REF_CHECK_MAX_NREF
97 # define REF_CHECK_MAX_NREF 0
99 #ifndef REF_CHECK_MIN_NREF
100 # define REF_CHECK_MIN_NREF 0
105 #ifndef REF_CHECK_STACK
106 #define REF_CHECK_STACK 0
109 #ifndef REF_CHECK_STACK
110 #define REF_CHECK_STACK 0
118 #ifndef REF_CHECK_MAX_NREF
119 #define REF_CHECK_MAX_NREF 1
122 #ifndef REF_CHECK_MIN_NREF
123 #define REF_CHECK_MIN_NREF 1
126 #ifndef REF_USE_LOCKS
127 # if HAVE_STHREAD || HAVE_CREATETHREAD || HAVE_PTHREAD
128 # define REF_USE_LOCKS 1
132 #ifndef REF_ALWAYS_USE_LOCKS
133 # define REF_ALWAYS_USE_LOCKS 1
138 #ifndef HAVE_SBRK_DEC
139 extern "C" void * sbrk(ssize_t);
141 #define DO_REF_CHECK_STACK(p) (((void*) (p) > sbrk(0)) && (p)->managed())
142 #else // REF_CHECK_STACK
143 #define DO_REF_CHECK_STACK(p) (0)
144 #endif // REF_CHECK_STACK
147 #define DO_REF_UNMANAGE(p) ((p)->unmanage())
149 #define DO_REF_UNMANAGE(p)
153 #define __REF_LOCK__(p) p->lock_ptr()
154 #define __REF_UNLOCK__(p) p->unlock_ptr()
155 #if REF_ALWAYS_USE_LOCKS
156 #define __REF_INITLOCK__() use_locks(true)
158 #define __REF_INITLOCK__() ref_lock_ = 0xff
161 #define __REF_LOCK__(p)
162 #define __REF_UNLOCK__(p)
163 #define __REF_INITLOCK__()
168 typedef unsigned long refcount_t;
197 # define REF_MAX_NREF (UINT_MAX - 1)
198 # define REF_MANAGED_CODE UINT_MAX
200 # define REF_MAX_NREF UINT_MAX
202 unsigned int _reference_count_;
204 unsigned char ref_lock_;
207 void error(
const char*)
const;
208 void too_many_refs()
const;
209 void not_enough_refs()
const;
236 if (!managed())
return 1;
238 return _reference_count_;
244 if (!managed())
return 1;
247 # if REF_CHECK_MAX_NREF
248 if (_reference_count_ >= REF_MAX_NREF) too_many_refs();
251 refcount_t r = _reference_count_;
252 __REF_UNLOCK__(
this);
259 if (!managed())
return 1;
262 # if REF_CHECK_MIN_NREF
263 if (_reference_count_ == 0) not_enough_refs();
266 refcount_t r = _reference_count_;
267 __REF_UNLOCK__(
this);
272 int managed()
const {
273 return _reference_count_ != REF_MANAGED_CODE;
281 _reference_count_ = REF_MANAGED_CODE;
295 void warn (
const char * msg)
const;
304 void ref_info(std::ostream& os)
const;
305 void check_pointer()
const;
387 operator T*()
const {
return p; }
393 int null()
const {
return p == 0; }
400 template <
class A>
int operator>=(
const Ref<A>&a)
const
402 template <
class A>
int operator<=(const Ref<A>&a)
const
404 template <
class A>
int operator>(
const Ref<A>&a)
const
405 {
return gt(p,a.pointer()); }
406 template <
class A>
int operator<(const Ref<A>&a)
const
407 {
return lt(p,a.pointer()); }
408 template <
class A>
int operator!=(
const Ref<A>&a)
const
409 {
return ne(p,a.pointer()); }
413 return eq(p,a.p)?0:((lt(p,a.p)?-1:1));
419 int ref = dereference(p);
467 T* cr =
dynamic_cast<T*
>(a);
482 if (DO_REF_CHECK_STACK(cr)) {
494 if (p && p->nreference() <= 0) {