39 #ifndef CGU_SHARED_HANDLE_H
40 #define CGU_SHARED_HANDLE_H
57 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
240 std::free(const_cast<void*>(obj));
259 g_free(const_cast<void*>(obj));
302 g_slice_free1(
sizeof(*obj), (
void*)obj);
367 template <
class U>
void destroy(U& obj) {obj.~U();}
371 g_slice_free1(
sizeof(*obj), (
void*)obj);
410 g_slice_free1(block_size, const_cast<void*>(obj));
437 template <
class T,
class Dealloc>
class SharedHandle;
438 template <
class T,
class Dealloc>
class ScopedHandle;
513 virtual const char*
what()
const throw() {
return "SharedHandleError\n";}
526 namespace SharedHandleAllocFail {
530 template <
class T,
class Dealloc = StandardArrayDelete<T>>
class SharedHandle {
534 #ifndef DOXYGEN_PARSING
536 unsigned int* ref_count_p;
542 if (!ref_items.ref_count_p)
return;
543 --(*ref_items.ref_count_p);
544 if (*ref_items.ref_count_p == 0) {
545 #ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
546 g_slice_free(
unsigned int, ref_items.ref_count_p);
548 delete ref_items.ref_count_p;
550 deleter(ref_items.obj);
555 if (!ref_items.ref_count_p)
return;
556 ++(*ref_items.ref_count_p);
580 if ((ref_items.obj = ptr)) {
581 #ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
582 ref_items.ref_count_p = g_slice_new(
unsigned int);
583 *ref_items.ref_count_p = 1;
586 ref_items.ref_count_p =
new unsigned int(1);
596 else ref_items.ref_count_p = 0;
628 if ((ref_items.obj = ptr)) {
629 #ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
630 ref_items.ref_count_p = g_slice_new(
unsigned int);
631 *ref_items.ref_count_p = 1;
634 ref_items.ref_count_p =
new unsigned int(1);
636 catch (std::bad_alloc&) {
641 else ref_items.ref_count_p = 0;
717 ref_items = sh_hand.ref_items;
726 ref_items = sh_hand.ref_items;
727 sh_hand.ref_items.ref_count_p = 0;
728 sh_hand.ref_items.obj = 0;
751 T
get()
const {
return ref_items.obj;}
758 operator T()
const {
return ref_items.obj;}
765 unsigned int get_refcount()
const {
return (ref_items.ref_count_p) ? *ref_items.ref_count_p : 0;}
826 template <
class T,
class Dealloc = StandardArrayDelete<T>>
class ScopedHandle {
861 if (ptr) deleter(ptr);
870 T
release() {T tmp = obj; obj = 0;
return tmp;}
877 T
get()
const {
return obj;}
884 operator T()
const {
return obj;}
1015 #ifndef DOXYGEN_PARSING
1017 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1019 unsigned int* ref_count_p;
1030 void unreference() {
1035 if (!ref_items.ref_count_p)
return;
1036 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1037 ref_items.mutex_p->
lock();
1038 --(*ref_items.ref_count_p);
1039 if (*ref_items.ref_count_p == 0) {
1040 # ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
1041 g_slice_free(
unsigned int, ref_items.ref_count_p);
1043 delete ref_items.ref_count_p;
1045 ref_items.mutex_p->unlock();
1046 delete ref_items.mutex_p;
1047 deleter(ref_items.obj);
1049 else ref_items.mutex_p->unlock();
1051 if (g_atomic_int_dec_and_test(ref_items.ref_count_p)) {
1052 # ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
1053 g_slice_free(gint, ref_items.ref_count_p);
1055 delete ref_items.ref_count_p;
1057 deleter(ref_items.obj);
1069 if (!ref_items.ref_count_p)
return;
1070 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1072 ++(*ref_items.ref_count_p);
1074 g_atomic_int_inc(ref_items.ref_count_p);
1108 if ((ref_items.obj = ptr)) {
1109 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1119 # ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
1120 ref_items.ref_count_p = g_slice_new(
unsigned int);
1121 *ref_items.ref_count_p = 1;
1124 ref_items.ref_count_p =
new unsigned int(1);
1127 delete ref_items.mutex_p;
1133 # ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
1134 ref_items.ref_count_p = g_slice_new(gint);
1135 *ref_items.ref_count_p = 1;
1138 ref_items.ref_count_p =
new gint(1);
1150 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1151 ref_items.mutex_p = 0;
1153 ref_items.ref_count_p = 0;
1196 if ((ref_items.obj = ptr)) {
1197 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1201 catch (std::bad_alloc&) {
1207 # ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
1208 ref_items.ref_count_p = g_slice_new(
unsigned int);
1209 *ref_items.ref_count_p = 1;
1212 ref_items.ref_count_p =
new unsigned int(1);
1214 catch (std::bad_alloc&) {
1215 delete ref_items.mutex_p;
1220 # ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
1221 ref_items.ref_count_p = g_slice_new(gint);
1222 *ref_items.ref_count_p = 1;
1225 ref_items.ref_count_p =
new gint(1);
1227 catch (std::bad_alloc&) {
1234 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1235 ref_items.mutex_p = 0;
1237 ref_items.ref_count_p = 0;
1345 ref_items = sh_hand.ref_items;
1354 ref_items = sh_hand.ref_items;
1355 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1356 sh_hand.ref_items.mutex_p = 0;
1358 sh_hand.ref_items.ref_count_p = 0;
1359 sh_hand.ref_items.obj = 0;
1372 std::swap(ref_items, sh_hand.ref_items);
1381 T
get()
const {
return ref_items.obj;}
1388 operator T()
const {
return ref_items.obj;}
1400 if (!ref_items.ref_count_p)
return 0;
1401 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1403 return *ref_items.ref_count_p;
1405 return g_atomic_int_get(ref_items.ref_count_p);
1416 #if defined(CGU_USE_SMART_PTR_COMPARISON) || defined(DOXYGEN_PARSING)
1428 template <
class T,
class Dealloc>
1430 return (s1.
get() == s2.
get());
1441 template <
class T,
class Dealloc>
1459 template <
class T,
class Dealloc>
1461 return std::less<T>()(s1.get(), s2.get());
1472 template <
class T,
class Dealloc>
1474 return (s1.
get() == s2.
get());
1485 template <
class T,
class Dealloc>
1498 template <
class T,
class Dealloc>
1500 return std::less<T>()(s1.get(), s2.get());
1503 #endif // CGU_USE_SMART_PTR_COMPARISON
1510 #if defined(CGU_USE_SMART_PTR_COMPARISON) && !defined(DOXYGEN_PARSING)
1514 template <
class T,
class Dealloc>
1515 struct hash<Cgu::SharedHandle<T, Dealloc>> {
1516 typedef std::size_t result_type;
1518 result_type operator()(
const argument_type& s)
const {
1525 template <
class T,
class Dealloc>
1526 struct hash<Cgu::SharedLockHandle<T, Dealloc>> {
1527 typedef std::size_t result_type;
1529 result_type operator()(
const argument_type& s)
const {
1537 #endif // CGU_USE_SMART_PTR_COMPARISON