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);
565 void reference() noexcept {
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 noexcept {
return ref_items.obj;}
769 operator T() const noexcept {
return ref_items.obj;}
776 unsigned int get_refcount() const noexcept {
return (ref_items.ref_count_p) ? *ref_items.ref_count_p : 0;}
825 template <
class T,
class Dealloc = StandardArrayDelete<T>>
class ScopedHandle {
861 reset(sc_hand.release());
886 if (ptr) deleter(ptr);
895 T
release() noexcept {T tmp = obj; obj = 0;
return tmp;}
902 T
get()
const noexcept {
return obj;}
909 operator T() const noexcept {
return obj;}
1060 #ifndef DOXYGEN_PARSING
1062 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1064 unsigned int* ref_count_p;
1075 void unreference() {
1080 if (!ref_items.ref_count_p)
return;
1081 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1082 ref_items.mutex_p->
lock();
1083 --(*ref_items.ref_count_p);
1084 if (*ref_items.ref_count_p == 0) {
1085 # ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
1086 g_slice_free(
unsigned int, ref_items.ref_count_p);
1088 delete ref_items.ref_count_p;
1090 ref_items.mutex_p->unlock();
1091 delete ref_items.mutex_p;
1092 deleter(ref_items.obj);
1094 else ref_items.mutex_p->unlock();
1096 if (g_atomic_int_dec_and_test(ref_items.ref_count_p)) {
1097 # ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
1098 g_slice_free(gint, ref_items.ref_count_p);
1100 delete ref_items.ref_count_p;
1102 deleter(ref_items.obj);
1109 void reference() noexcept {
1114 if (!ref_items.ref_count_p)
return;
1115 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1117 ++(*ref_items.ref_count_p);
1119 g_atomic_int_inc(ref_items.ref_count_p);
1153 if ((ref_items.obj = ptr)) {
1154 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1164 # ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
1165 ref_items.ref_count_p = g_slice_new(
unsigned int);
1166 *ref_items.ref_count_p = 1;
1169 ref_items.ref_count_p =
new unsigned int(1);
1172 delete ref_items.mutex_p;
1178 # ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
1179 ref_items.ref_count_p = g_slice_new(gint);
1180 *ref_items.ref_count_p = 1;
1183 ref_items.ref_count_p =
new gint(1);
1195 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1196 ref_items.mutex_p = 0;
1198 ref_items.ref_count_p = 0;
1241 if ((ref_items.obj = ptr)) {
1242 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1246 catch (std::bad_alloc&) {
1252 # ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
1253 ref_items.ref_count_p = g_slice_new(
unsigned int);
1254 *ref_items.ref_count_p = 1;
1257 ref_items.ref_count_p =
new unsigned int(1);
1259 catch (std::bad_alloc&) {
1260 delete ref_items.mutex_p;
1265 # ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
1266 ref_items.ref_count_p = g_slice_new(gint);
1267 *ref_items.ref_count_p = 1;
1270 ref_items.ref_count_p =
new gint(1);
1272 catch (std::bad_alloc&) {
1279 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1280 ref_items.mutex_p = 0;
1282 ref_items.ref_count_p = 0;
1390 ref_items = sh_hand.ref_items;
1399 ref_items = sh_hand.ref_items;
1400 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1401 sh_hand.ref_items.mutex_p = 0;
1403 sh_hand.ref_items.ref_count_p = 0;
1404 sh_hand.ref_items.obj = 0;
1417 std::swap(ref_items, sh_hand.ref_items);
1426 T
get()
const noexcept {
return ref_items.obj;}
1433 operator T() const noexcept {
return ref_items.obj;}
1445 if (!ref_items.ref_count_p)
return 0;
1446 #ifdef CGU_SHARED_LOCK_HANDLE_USE_MUTEX
1448 return *ref_items.ref_count_p;
1450 return g_atomic_int_get(ref_items.ref_count_p);
1461 #if defined(CGU_USE_SMART_PTR_COMPARISON) || defined(DOXYGEN_PARSING)
1473 template <
class T,
class Dealloc>
1475 return (s1.get() == s2.get());
1486 template <
class T,
class Dealloc>
1505 template <
class T,
class Dealloc>
1507 return std::less<T>()(s1.get(), s2.get());
1518 template <
class T,
class Dealloc>
1520 return (s1.get() == s2.get());
1531 template <
class T,
class Dealloc>
1545 template <
class T,
class Dealloc>
1547 return std::less<T>()(s1.get(), s2.get());
1550 #endif // CGU_USE_SMART_PTR_COMPARISON
1557 #if defined(CGU_USE_SMART_PTR_COMPARISON) && !defined(DOXYGEN_PARSING)
1561 template <
class T,
class Dealloc>
1562 struct hash<
Cgu::SharedHandle<T, Dealloc>> {
1563 typedef std::size_t result_type;
1565 result_type operator()(
const argument_type& s)
const {
1572 template <
class T,
class Dealloc>
1573 struct hash<
Cgu::SharedLockHandle<T, Dealloc>> {
1574 typedef std::size_t result_type;
1576 result_type operator()(
const argument_type& s)
const {
1584 #endif // CGU_USE_SMART_PTR_COMPARISON
bool operator!=(const GobjHandle< T > &h1, const GobjHandle< T > &h2) noexcept
Definition: gobj_handle.h:613
A deleter functor for use as the second (Dealloc) template parameter of the SharedHandle, SharedLockHandle or ScopedHandle template classes, which calls the C++ delete[] expression.
Definition: shared_handle.h:232
int lock() noexcept
Definition: mutex.h:147
Definition: shared_handle.h:538
T release() noexcept
Definition: shared_handle.h:895
SharedLockHandle(T ptr, Cgu::SharedHandleAllocFail::Leave tag)
Definition: shared_handle.h:1239
void swap(Cgu::AsyncQueue< T, Container > &q1, Cgu::AsyncQueue< T, Container > &q2)
Definition: async_queue.h:1483
~ScopedHandle()
Definition: shared_handle.h:915
void reset(T ptr, Cgu::SharedHandleAllocFail::Leave tag)
Definition: shared_handle.h:1380
void operator()(T obj) noexcept
Definition: shared_handle.h:312
SharedHandle< gchar *, GFree > GcharSharedHandle
A handle comprising a typed instance of the SharedHandle class for gchar* arrays and strings...
Definition: shared_handle.h:459
void reset(T ptr=0)
Definition: shared_handle.h:679
SharedHandle(T ptr, Cgu::SharedHandleAllocFail::Leave tag)
Definition: shared_handle.h:637
bool operator==(const GobjHandle< T > &h1, const GobjHandle< T > &h2) noexcept
Definition: gobj_handle.h:600
SharedHandle(SharedHandle &&sh_hand) noexcept
Definition: shared_handle.h:736
ScopedHandle & operator=(const ScopedHandle &)=delete
void operator()(const void *obj) noexcept
Definition: shared_handle.h:420
A specialization of std::hash for Cgu::Callback::FunctorArg, Cgu::Callback::SafeFunctorArg, Cgu::GobjHandle, Cgu::GvarHandle, Cgu::IntrusivePtr, Cgu::SharedHandle, Cgu::SharedLockHandle, Cgu::SharedPtr and Cgu::SharedLockPtr so that such objects may be keys of unordered associative containers.
A deleter functor for use as the second (Dealloc) template parameter of the SharedHandle, SharedLockHandle or ScopedHandle template classes, which calls std::free.
Definition: shared_handle.h:248
void operator()(T obj)
Definition: shared_handle.h:380
This is a generic class for managing the lifetime of objects allocated on freestore.
Definition: shared_handle.h:448
A deleter functor for use as the second (Dealloc) template parameter of the SharedHandle, SharedLockHandle or ScopedHandle template classes, which calls glib's g_slice_free1().
Definition: shared_handle.h:418
SharedHandleError(T p)
Definition: shared_handle.h:525
ScopedHandle(const ScopedHandle &)=delete
void operator()(const void *obj) noexcept
Definition: shared_handle.h:250
SharedLockHandle & operator=(SharedLockHandle sh_hand)
Definition: shared_handle.h:1416
A deleter functor for use as the second (Dealloc) template parameter of the SharedHandle, SharedLockHandle or ScopedHandle template classes, which calls glib's g_free().
Definition: shared_handle.h:267
A scoped locking class for exception safe Mutex locking.
Definition: mutex.h:207
void operator()(const void *obj) noexcept
Definition: shared_handle.h:269
A wrapper class for pthread mutexes.
Definition: mutex.h:117
SharedLockHandle(SharedLockHandle &&sh_hand) noexcept
Definition: shared_handle.h:1398
unsigned int get_refcount() const noexcept
Definition: shared_handle.h:1444
virtual const char * what() const
Definition: shared_handle.h:524
ScopedHandle(ScopedHandle &&sc_hand) noexcept
Definition: shared_handle.h:846
ScopedHandle< gchar *, GFree > GcharScopedHandle
A handle comprising a typed instance of the ScopedHandle class for gchar* arrays and strings...
Definition: shared_handle.h:469
This is a generic scoped class for managing the lifetime of objects allocated on freestore.
Definition: shared_handle.h:449
Provides wrapper classes for pthread mutexes and condition variables, and scoped locking classes for ...
Definition: application.h:44
Leave
Definition: shared_handle.h:538
void operator()(T obj)
Definition: shared_handle.h:234
void reset(T ptr=0)
Definition: shared_handle.h:884
SharedLockHandle(const SharedLockHandle &sh_hand) noexcept
Definition: shared_handle.h:1389
A deleter functor for use as the second (Dealloc) template parameter of the SharedHandle, SharedLockHandle or ScopedHandle template classes, which calls glib's g_slice_free1(), but before doing so also explicitly calls the destructor of a C++ object constructed in the memory.
Definition: shared_handle.h:377
This is an exception struct thrown as an alternative to deleting a managed object when internal memor...
Definition: shared_handle.h:522
SharedLockHandle(T ptr=0)
Definition: shared_handle.h:1151
SharedHandle(T ptr=0)
Definition: shared_handle.h:589
SharedHandle & operator=(SharedHandle sh_hand)
Definition: shared_handle.h:752
~SharedLockHandle()
Definition: shared_handle.h:1458
unsigned int get_refcount() const noexcept
Definition: shared_handle.h:776
ScopedHandle(T ptr=0) noexcept
Definition: shared_handle.h:874
~SharedHandle()
Definition: shared_handle.h:782
void reset(T ptr, Cgu::SharedHandleAllocFail::Leave tag)
Definition: shared_handle.h:718
void reset(T ptr=0)
Definition: shared_handle.h:1324
SharedHandle(const SharedHandle &sh_hand) noexcept
Definition: shared_handle.h:727
This is a generic class for managing the lifetime of objects allocated on freestore, with a thread safe reference count..
Definition: shared_handle.h:1056
ScopedHandle & operator=(ScopedHandle &&sc_hand)
Definition: shared_handle.h:860
A deleter functor for use as the second (Dealloc) template parameter of the SharedHandle, SharedLockHandle or ScopedHandle template classes, which calls glib's g_slice_free1().
Definition: shared_handle.h:310
T obj
Definition: shared_handle.h:523