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;}
836 template <
class T,
class Dealloc = StandardArrayDelete<T>>
class ScopedHandle {
871 if (ptr) deleter(ptr);
880 T
release() {T tmp = obj; obj = 0;
return tmp;}
887 T
get()
const {
return obj;}
894 operator T()
const {
return obj;}
1041 #ifndef DOXYGEN_PARSING
1043 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1045 unsigned int* ref_count_p;
1056 void unreference() {
1061 if (!ref_items.ref_count_p)
return;
1062 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1063 ref_items.mutex_p->
lock();
1064 --(*ref_items.ref_count_p);
1065 if (*ref_items.ref_count_p == 0) {
1066 # ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
1067 g_slice_free(
unsigned int, ref_items.ref_count_p);
1069 delete ref_items.ref_count_p;
1071 ref_items.mutex_p->unlock();
1072 delete ref_items.mutex_p;
1073 deleter(ref_items.obj);
1075 else ref_items.mutex_p->unlock();
1077 if (g_atomic_int_dec_and_test(ref_items.ref_count_p)) {
1078 # ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
1079 g_slice_free(gint, ref_items.ref_count_p);
1081 delete ref_items.ref_count_p;
1083 deleter(ref_items.obj);
1095 if (!ref_items.ref_count_p)
return;
1096 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1098 ++(*ref_items.ref_count_p);
1100 g_atomic_int_inc(ref_items.ref_count_p);
1134 if ((ref_items.obj = ptr)) {
1135 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1145 # ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
1146 ref_items.ref_count_p = g_slice_new(
unsigned int);
1147 *ref_items.ref_count_p = 1;
1150 ref_items.ref_count_p =
new unsigned int(1);
1153 delete ref_items.mutex_p;
1159 # ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
1160 ref_items.ref_count_p = g_slice_new(gint);
1161 *ref_items.ref_count_p = 1;
1164 ref_items.ref_count_p =
new gint(1);
1176 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1177 ref_items.mutex_p = 0;
1179 ref_items.ref_count_p = 0;
1222 if ((ref_items.obj = ptr)) {
1223 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1227 catch (std::bad_alloc&) {
1233 # ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
1234 ref_items.ref_count_p = g_slice_new(
unsigned int);
1235 *ref_items.ref_count_p = 1;
1238 ref_items.ref_count_p =
new unsigned int(1);
1240 catch (std::bad_alloc&) {
1241 delete ref_items.mutex_p;
1246 # ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
1247 ref_items.ref_count_p = g_slice_new(gint);
1248 *ref_items.ref_count_p = 1;
1251 ref_items.ref_count_p =
new gint(1);
1253 catch (std::bad_alloc&) {
1260 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1261 ref_items.mutex_p = 0;
1263 ref_items.ref_count_p = 0;
1371 ref_items = sh_hand.ref_items;
1380 ref_items = sh_hand.ref_items;
1381 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1382 sh_hand.ref_items.mutex_p = 0;
1384 sh_hand.ref_items.ref_count_p = 0;
1385 sh_hand.ref_items.obj = 0;
1398 std::swap(ref_items, sh_hand.ref_items);
1407 T
get()
const {
return ref_items.obj;}
1414 operator T()
const {
return ref_items.obj;}
1426 if (!ref_items.ref_count_p)
return 0;
1427 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1429 return *ref_items.ref_count_p;
1431 return g_atomic_int_get(ref_items.ref_count_p);
1442 #if defined(CGU_USE_SMART_PTR_COMPARISON) || defined(DOXYGEN_PARSING)
1454 template <
class T,
class Dealloc>
1456 return (s1.get() == s2.get());
1467 template <
class T,
class Dealloc>
1485 template <
class T,
class Dealloc>
1487 return std::less<T>()(s1.get(), s2.get());
1498 template <
class T,
class Dealloc>
1500 return (s1.
get() == s2.
get());
1511 template <
class T,
class Dealloc>
1524 template <
class T,
class Dealloc>
1526 return std::less<T>()(s1.get(), s2.get());
1529 #endif // CGU_USE_SMART_PTR_COMPARISON
1536 #if defined(CGU_USE_SMART_PTR_COMPARISON) && !defined(DOXYGEN_PARSING)
1540 template <
class T,
class Dealloc>
1541 struct hash<Cgu::SharedHandle<T, Dealloc>> {
1542 typedef std::size_t result_type;
1544 result_type operator()(
const argument_type& s)
const {
1551 template <
class T,
class Dealloc>
1552 struct hash<Cgu::SharedLockHandle<T, Dealloc>> {
1553 typedef std::size_t result_type;
1555 result_type operator()(
const argument_type& s)
const {
1563 #endif // CGU_USE_SMART_PTR_COMPARISON