39 #ifndef CGU_SHARED_HANDLE_H
40 #define CGU_SHARED_HANDLE_H
56 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
251 std::free(const_cast<void*>(obj));
270 g_free(const_cast<void*>(obj));
313 g_slice_free1(
sizeof(*obj), (
void*)obj);
378 template <
class U>
void destroy(U& obj) {obj.~U();}
382 g_slice_free1(
sizeof(*obj), (
void*)obj);
421 g_slice_free1(block_size, const_cast<void*>(obj));
524 virtual const char*
what()
const throw() {
return "SharedHandleError\n";}
537 namespace SharedHandleAllocFail {
541 template <
class T,
class Dealloc = StandardArrayDelete<T>>
class SharedHandle {
545 #ifndef DOXYGEN_PARSING
547 unsigned int* ref_count_p;
553 if (!ref_items.ref_count_p)
return;
554 --(*ref_items.ref_count_p);
555 if (*ref_items.ref_count_p == 0) {
556 #ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
557 g_slice_free(
unsigned int, ref_items.ref_count_p);
559 delete ref_items.ref_count_p;
561 deleter(ref_items.obj);
566 if (!ref_items.ref_count_p)
return;
567 ++(*ref_items.ref_count_p);
591 if ((ref_items.obj = ptr)) {
592 #ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
593 ref_items.ref_count_p = g_slice_new(
unsigned int);
594 *ref_items.ref_count_p = 1;
597 ref_items.ref_count_p =
new unsigned int(1);
607 else ref_items.ref_count_p = 0;
639 if ((ref_items.obj = ptr)) {
640 #ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
641 ref_items.ref_count_p = g_slice_new(
unsigned int);
642 *ref_items.ref_count_p = 1;
645 ref_items.ref_count_p =
new unsigned int(1);
647 catch (std::bad_alloc&) {
652 else ref_items.ref_count_p = 0;
728 ref_items = sh_hand.ref_items;
737 ref_items = sh_hand.ref_items;
738 sh_hand.ref_items.ref_count_p = 0;
739 sh_hand.ref_items.obj = 0;
762 T
get()
const {
return ref_items.obj;}
769 operator T()
const {
return ref_items.obj;}
776 unsigned int get_refcount()
const {
return (ref_items.ref_count_p) ? *ref_items.ref_count_p : 0;}
833 template <
class T,
class Dealloc = StandardArrayDelete<T>>
class ScopedHandle {
869 reset(sc_hand.release());
894 if (ptr) deleter(ptr);
903 T
release() {T tmp = obj; obj = 0;
return tmp;}
910 T
get()
const {
return obj;}
917 operator T()
const {
return obj;}
1064 #ifndef DOXYGEN_PARSING
1066 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1068 unsigned int* ref_count_p;
1079 void unreference() {
1084 if (!ref_items.ref_count_p)
return;
1085 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1086 ref_items.mutex_p->
lock();
1087 --(*ref_items.ref_count_p);
1088 if (*ref_items.ref_count_p == 0) {
1089 # ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
1090 g_slice_free(
unsigned int, ref_items.ref_count_p);
1092 delete ref_items.ref_count_p;
1094 ref_items.mutex_p->unlock();
1095 delete ref_items.mutex_p;
1096 deleter(ref_items.obj);
1098 else ref_items.mutex_p->unlock();
1100 if (g_atomic_int_dec_and_test(ref_items.ref_count_p)) {
1101 # ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
1102 g_slice_free(gint, ref_items.ref_count_p);
1104 delete ref_items.ref_count_p;
1106 deleter(ref_items.obj);
1118 if (!ref_items.ref_count_p)
return;
1119 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1121 ++(*ref_items.ref_count_p);
1123 g_atomic_int_inc(ref_items.ref_count_p);
1157 if ((ref_items.obj = ptr)) {
1158 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1168 # ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
1169 ref_items.ref_count_p = g_slice_new(
unsigned int);
1170 *ref_items.ref_count_p = 1;
1173 ref_items.ref_count_p =
new unsigned int(1);
1176 delete ref_items.mutex_p;
1182 # ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
1183 ref_items.ref_count_p = g_slice_new(gint);
1184 *ref_items.ref_count_p = 1;
1187 ref_items.ref_count_p =
new gint(1);
1199 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1200 ref_items.mutex_p = 0;
1202 ref_items.ref_count_p = 0;
1245 if ((ref_items.obj = ptr)) {
1246 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1250 catch (std::bad_alloc&) {
1256 # ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
1257 ref_items.ref_count_p = g_slice_new(
unsigned int);
1258 *ref_items.ref_count_p = 1;
1261 ref_items.ref_count_p =
new unsigned int(1);
1263 catch (std::bad_alloc&) {
1264 delete ref_items.mutex_p;
1269 # ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
1270 ref_items.ref_count_p = g_slice_new(gint);
1271 *ref_items.ref_count_p = 1;
1274 ref_items.ref_count_p =
new gint(1);
1276 catch (std::bad_alloc&) {
1283 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1284 ref_items.mutex_p = 0;
1286 ref_items.ref_count_p = 0;
1394 ref_items = sh_hand.ref_items;
1403 ref_items = sh_hand.ref_items;
1404 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1405 sh_hand.ref_items.mutex_p = 0;
1407 sh_hand.ref_items.ref_count_p = 0;
1408 sh_hand.ref_items.obj = 0;
1421 std::swap(ref_items, sh_hand.ref_items);
1430 T
get()
const {
return ref_items.obj;}
1437 operator T()
const {
return ref_items.obj;}
1449 if (!ref_items.ref_count_p)
return 0;
1450 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1452 return *ref_items.ref_count_p;
1454 return g_atomic_int_get(ref_items.ref_count_p);
1465 #if defined(CGU_USE_SMART_PTR_COMPARISON) || defined(DOXYGEN_PARSING)
1477 template <
class T,
class Dealloc>
1479 return (s1.get() == s2.get());
1490 template <
class T,
class Dealloc>
1508 template <
class T,
class Dealloc>
1510 return std::less<T>()(s1.get(), s2.get());
1521 template <
class T,
class Dealloc>
1523 return (s1.
get() == s2.
get());
1534 template <
class T,
class Dealloc>
1547 template <
class T,
class Dealloc>
1549 return std::less<T>()(s1.get(), s2.get());
1552 #endif // CGU_USE_SMART_PTR_COMPARISON
1559 #if defined(CGU_USE_SMART_PTR_COMPARISON) && !defined(DOXYGEN_PARSING)
1563 template <
class T,
class Dealloc>
1564 struct hash<Cgu::SharedHandle<T, Dealloc>> {
1565 typedef std::size_t result_type;
1567 result_type operator()(
const argument_type& s)
const {
1574 template <
class T,
class Dealloc>
1575 struct hash<Cgu::SharedLockHandle<T, Dealloc>> {
1576 typedef std::size_t result_type;
1578 result_type operator()(
const argument_type& s)
const {
1586 #endif // CGU_USE_SMART_PTR_COMPARISON