2 #ifndef __MONO_UTILS_REFCOUNT_H__
3 #define __MONO_UTILS_REFCOUNT_H__
11 * Mechanism for ref-counting which tries to be as user-friendly as possible. Instead of being a wrapper around
12 * user-provided data, it is embedded into the user data.
14 * This introduces some constraints on the MonoRefCount field:
15 * - it needs to be called "ref"
16 * - it cannot be a pointer
21 void (*destructor) (gpointer data);
24 #define mono_refcount_init(v,destructor) do { mono_refcount_initialize (&(v)->ref, (destructor)); } while (0)
25 #define mono_refcount_inc(v) (mono_refcount_increment (&(v)->ref),(v))
26 #define mono_refcount_tryinc(v) (mono_refcount_tryincrement (&(v)->ref))
27 #define mono_refcount_dec(v) do { mono_refcount_decrement (&(v)->ref); } while (0)
30 mono_refcount_initialize (MonoRefCount *refcount, void (*destructor) (gpointer data))
33 refcount->destructor = destructor;
36 static inline gboolean
37 mono_refcount_tryincrement (MonoRefCount *refcount)
39 guint32 oldref, newref;
44 oldref = refcount->ref;
49 } while (InterlockedCompareExchange ((gint32*) &refcount->ref, newref, oldref) != oldref);
55 mono_refcount_increment (MonoRefCount *refcount)
57 if (!mono_refcount_tryincrement (refcount))
58 g_error ("%s: cannot increment a ref with value 0", __func__);
62 mono_refcount_decrement (MonoRefCount *refcount)
64 guint32 oldref, newref;
69 oldref = refcount->ref;
71 g_error ("%s: cannot decrement a ref with value 0", __func__);
74 } while (InterlockedCompareExchange ((gint32*) &refcount->ref, newref, oldref) != oldref);
76 if (newref == 0 && refcount->destructor)
77 refcount->destructor ((gpointer) refcount);
80 #endif /* __MONO_UTILS_REFCOUNT_H__ */