39 #ifndef CGU_SHARED_HANDLE_H
40 #define CGU_SHARED_HANDLE_H
56 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
252 std::free(const_cast<void*>(obj));
271 g_free(const_cast<void*>(obj));
314 g_slice_free1(
sizeof(*obj), (
void*)obj);
379 template <
class U>
void destroy(U& obj) {obj.~U();}
383 g_slice_free1(
sizeof(*obj), (
void*)obj);
422 g_slice_free1(block_size, const_cast<void*>(obj));
525 virtual const char*
what()
const throw() {
return "SharedHandleError\n";}
538 namespace SharedHandleAllocFail {
542 template <
class T,
class Dealloc = StandardArrayDelete<T>>
class SharedHandle {
546 #ifndef DOXYGEN_PARSING
548 unsigned int* ref_count_p;
554 if (!ref_items.ref_count_p)
return;
555 --(*ref_items.ref_count_p);
556 if (*ref_items.ref_count_p == 0) {
557 #ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
558 g_slice_free(
unsigned int, ref_items.ref_count_p);
560 delete ref_items.ref_count_p;
562 deleter(ref_items.obj);
567 if (!ref_items.ref_count_p)
return;
568 ++(*ref_items.ref_count_p);
592 if ((ref_items.obj = ptr)) {
593 #ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
594 ref_items.ref_count_p = g_slice_new(
unsigned int);
595 *ref_items.ref_count_p = 1;
598 ref_items.ref_count_p =
new unsigned int(1);
608 else ref_items.ref_count_p = 0;
640 if ((ref_items.obj = ptr)) {
641 #ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
642 ref_items.ref_count_p = g_slice_new(
unsigned int);
643 *ref_items.ref_count_p = 1;
646 ref_items.ref_count_p =
new unsigned int(1);
648 catch (std::bad_alloc&) {
653 else ref_items.ref_count_p = 0;
729 ref_items = sh_hand.ref_items;
738 ref_items = sh_hand.ref_items;
739 sh_hand.ref_items.ref_count_p = 0;
740 sh_hand.ref_items.obj = 0;
763 T
get()
const {
return ref_items.obj;}
770 operator T()
const {
return ref_items.obj;}
777 unsigned int get_refcount()
const {
return (ref_items.ref_count_p) ? *ref_items.ref_count_p : 0;}
838 template <
class T,
class Dealloc = StandardArrayDelete<T>>
class ScopedHandle {
873 if (ptr) deleter(ptr);
882 T
release() {T tmp = obj; obj = 0;
return tmp;}
889 T
get()
const {
return obj;}
896 operator T()
const {
return obj;}
1046 #ifndef DOXYGEN_PARSING
1048 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1050 unsigned int* ref_count_p;
1061 void unreference() {
1066 if (!ref_items.ref_count_p)
return;
1067 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1068 ref_items.mutex_p->
lock();
1069 --(*ref_items.ref_count_p);
1070 if (*ref_items.ref_count_p == 0) {
1071 # ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
1072 g_slice_free(
unsigned int, ref_items.ref_count_p);
1074 delete ref_items.ref_count_p;
1076 ref_items.mutex_p->unlock();
1077 delete ref_items.mutex_p;
1078 deleter(ref_items.obj);
1080 else ref_items.mutex_p->unlock();
1082 if (g_atomic_int_dec_and_test(ref_items.ref_count_p)) {
1083 # ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
1084 g_slice_free(gint, ref_items.ref_count_p);
1086 delete ref_items.ref_count_p;
1088 deleter(ref_items.obj);
1100 if (!ref_items.ref_count_p)
return;
1101 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1103 ++(*ref_items.ref_count_p);
1105 g_atomic_int_inc(ref_items.ref_count_p);
1139 if ((ref_items.obj = ptr)) {
1140 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1150 # ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
1151 ref_items.ref_count_p = g_slice_new(
unsigned int);
1152 *ref_items.ref_count_p = 1;
1155 ref_items.ref_count_p =
new unsigned int(1);
1158 delete ref_items.mutex_p;
1164 # ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
1165 ref_items.ref_count_p = g_slice_new(gint);
1166 *ref_items.ref_count_p = 1;
1169 ref_items.ref_count_p =
new gint(1);
1181 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1182 ref_items.mutex_p = 0;
1184 ref_items.ref_count_p = 0;
1227 if ((ref_items.obj = ptr)) {
1228 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1232 catch (std::bad_alloc&) {
1238 # ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
1239 ref_items.ref_count_p = g_slice_new(
unsigned int);
1240 *ref_items.ref_count_p = 1;
1243 ref_items.ref_count_p =
new unsigned int(1);
1245 catch (std::bad_alloc&) {
1246 delete ref_items.mutex_p;
1251 # ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
1252 ref_items.ref_count_p = g_slice_new(gint);
1253 *ref_items.ref_count_p = 1;
1256 ref_items.ref_count_p =
new gint(1);
1258 catch (std::bad_alloc&) {
1265 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1266 ref_items.mutex_p = 0;
1268 ref_items.ref_count_p = 0;
1376 ref_items = sh_hand.ref_items;
1385 ref_items = sh_hand.ref_items;
1386 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1387 sh_hand.ref_items.mutex_p = 0;
1389 sh_hand.ref_items.ref_count_p = 0;
1390 sh_hand.ref_items.obj = 0;
1403 std::swap(ref_items, sh_hand.ref_items);
1412 T
get()
const {
return ref_items.obj;}
1419 operator T()
const {
return ref_items.obj;}
1431 if (!ref_items.ref_count_p)
return 0;
1432 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1434 return *ref_items.ref_count_p;
1436 return g_atomic_int_get(ref_items.ref_count_p);
1447 #if defined(CGU_USE_SMART_PTR_COMPARISON) || defined(DOXYGEN_PARSING)
1459 template <
class T,
class Dealloc>
1461 return (s1.get() == s2.get());
1472 template <
class T,
class Dealloc>
1490 template <
class T,
class Dealloc>
1492 return std::less<T>()(s1.get(), s2.get());
1503 template <
class T,
class Dealloc>
1505 return (s1.
get() == s2.
get());
1516 template <
class T,
class Dealloc>
1529 template <
class T,
class Dealloc>
1531 return std::less<T>()(s1.get(), s2.get());
1534 #endif // CGU_USE_SMART_PTR_COMPARISON
1541 #if defined(CGU_USE_SMART_PTR_COMPARISON) && !defined(DOXYGEN_PARSING)
1545 template <
class T,
class Dealloc>
1546 struct hash<Cgu::SharedHandle<T, Dealloc>> {
1547 typedef std::size_t result_type;
1549 result_type operator()(
const argument_type& s)
const {
1556 template <
class T,
class Dealloc>
1557 struct hash<Cgu::SharedLockHandle<T, Dealloc>> {
1558 typedef std::size_t result_type;
1560 result_type operator()(
const argument_type& s)
const {
1568 #endif // CGU_USE_SMART_PTR_COMPARISON