--- deliantra/server/include/util.h 2011/12/31 06:18:01 1.116 +++ deliantra/server/include/util.h 2012/01/03 11:23:41 1.117 @@ -326,7 +326,6 @@ slice_alloc -= n * sizeof (T); if (DEBUG_POISON) memset (ptr, DEBUG_POISON, n * sizeof (T)); g_slice_free1 (n * sizeof (T), (void *)ptr); - assert (slice_alloc >= 0);//D } } @@ -452,6 +451,63 @@ } }; +// basically a memory area, but refcounted +struct refcnt_buf +{ + char *data; + + refcnt_buf (size_t size = 0); + refcnt_buf (void *data, size_t size); + + refcnt_buf (const refcnt_buf &src) + { + data = src.data; + ++_refcnt (); + } + + ~refcnt_buf (); + + refcnt_buf &operator =(const refcnt_buf &src); + + operator char *() + { + return data; + } + + size_t size () const + { + return _size (); + } + +protected: + enum { + overhead = sizeof (unsigned int) * 2 + }; + + unsigned int &_size () const + { + return ((unsigned int *)data)[-2]; + } + + unsigned int &_refcnt () const + { + return ((unsigned int *)data)[-1]; + } + + void _alloc (unsigned int size) + { + data = ((char *)salloc (size + overhead)) + overhead; + _size () = size; + _refcnt () = 1; + } + + void dec () + { + if (!--_refcnt ()) + sfree (data - overhead, size () + overhead); + } +}; + INTERFACE_CLASS (attachable) struct refcnt_base {