mirror of
https://gitlab.xiph.org/xiph/icecast-common.git
synced 2024-12-04 14:46:31 -05:00
Feature: Implemented weak refobject references
This commit is contained in:
parent
3028728484
commit
a98da37c93
@ -75,8 +75,9 @@ struct igloo_ro_type_tag {
|
||||
struct igloo_ro_base_tag {
|
||||
/* Type of the object */
|
||||
const igloo_ro_type_t * type;
|
||||
/* Reference counter */
|
||||
/* Reference counters */
|
||||
size_t refc;
|
||||
size_t wrefc;
|
||||
/* Mutex for igloo_ro_*(). */
|
||||
igloo_mutex_t lock;
|
||||
/* Name of the object. */
|
||||
@ -101,7 +102,7 @@ int igloo_ro_new__return_zero(igloo_ro_t self, const igloo_ro_type_t *type, va_l
|
||||
|
||||
#define igloo_RO_GET_TYPE(x) (igloo_RO__GETBASE((x)) == NULL ? NULL : igloo_RO__GETBASE((x))->type)
|
||||
#define igloo_RO_GET_TYPENAME(x) (igloo_RO_GET_TYPE((x)) == NULL ? NULL : igloo_RO_GET_TYPE((x))->type_name)
|
||||
#define igloo_RO_IS_VALID(x,type) (!igloo_RO_IS_NULL((x)) && igloo_RO_GET_TYPE((x)) == (igloo_ro__type__ ## type))
|
||||
#define igloo_RO_IS_VALID(x,type) (!igloo_RO_IS_NULL((x)) && igloo_RO_GET_TYPE((x)) == (igloo_ro__type__ ## type) && igloo_RO__GETBASE((x))->refc)
|
||||
#define igloo_RO_HAS_TYPE(x,type) (!igloo_RO_IS_NULL((x)) && igloo_RO_GET_TYPE((x)) == (type))
|
||||
|
||||
/* Create a new refobject
|
||||
@ -124,6 +125,10 @@ int igloo_ro_ref(igloo_ro_t self);
|
||||
*/
|
||||
int igloo_ro_unref(igloo_ro_t self);
|
||||
|
||||
/* This is the same as igloo_ro_ref() and igloo_ro_unref() but increases/decreases the week refernece counter. */
|
||||
int igloo_ro_weak_ref(igloo_ro_t self);
|
||||
int igloo_ro_weak_unref(igloo_ro_t self);
|
||||
|
||||
/* This gets the object's name */
|
||||
const char * igloo_ro_get_name(igloo_ro_t self);
|
||||
|
||||
|
74
src/ro.c
74
src/ro.c
@ -115,12 +115,24 @@ int igloo_ro_ref(igloo_ro_t self)
|
||||
return -1;
|
||||
|
||||
igloo_thread_mutex_lock(&(base->lock));
|
||||
if (!base->refc) {
|
||||
igloo_thread_mutex_unlock(&(base->lock));
|
||||
return -1;
|
||||
}
|
||||
base->refc++;
|
||||
igloo_thread_mutex_unlock(&(base->lock));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void igloo_ro__destory(igloo_ro_base_t *base)
|
||||
{
|
||||
igloo_thread_mutex_unlock(&(base->lock));
|
||||
igloo_thread_mutex_destroy(&(base->lock));
|
||||
|
||||
free(base);
|
||||
}
|
||||
|
||||
int igloo_ro_unref(igloo_ro_t self)
|
||||
{
|
||||
igloo_ro_base_t *base = igloo_RO__GETBASE(self);
|
||||
@ -129,6 +141,12 @@ int igloo_ro_unref(igloo_ro_t self)
|
||||
return -1;
|
||||
|
||||
igloo_thread_mutex_lock(&(base->lock));
|
||||
|
||||
if (!base->refc) {
|
||||
igloo_thread_mutex_unlock(&(base->lock));
|
||||
return -1;
|
||||
}
|
||||
|
||||
base->refc--;
|
||||
|
||||
if (base->refc) {
|
||||
@ -144,10 +162,47 @@ int igloo_ro_unref(igloo_ro_t self)
|
||||
if (base->name)
|
||||
free(base->name);
|
||||
|
||||
igloo_thread_mutex_unlock(&(base->lock));
|
||||
igloo_thread_mutex_destroy(&(base->lock));
|
||||
if (base->wrefc) {
|
||||
/* only clear the object */
|
||||
base->associated = igloo_RO_NULL;
|
||||
base->name = NULL;
|
||||
} else {
|
||||
igloo_ro__destory(base);
|
||||
}
|
||||
|
||||
free(base);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int igloo_ro_weak_ref(igloo_ro_t self)
|
||||
{
|
||||
igloo_ro_base_t *base = igloo_RO__GETBASE(self);
|
||||
|
||||
if (!base)
|
||||
return -1;
|
||||
|
||||
igloo_thread_mutex_lock(&(base->lock));
|
||||
base->wrefc++;
|
||||
igloo_thread_mutex_unlock(&(base->lock));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int igloo_ro_weak_unref(igloo_ro_t self)
|
||||
{
|
||||
igloo_ro_base_t *base = igloo_RO__GETBASE(self);
|
||||
|
||||
if (!base)
|
||||
return -1;
|
||||
|
||||
igloo_thread_mutex_lock(&(base->lock));
|
||||
base->wrefc--;
|
||||
|
||||
if (base->refc || base->wrefc) {
|
||||
igloo_thread_mutex_unlock(&(base->lock));
|
||||
return 0;
|
||||
}
|
||||
|
||||
igloo_ro__destory(base);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -161,6 +216,10 @@ const char * igloo_ro_get_name(igloo_ro_t self)
|
||||
return NULL;
|
||||
|
||||
igloo_thread_mutex_lock(&(base->lock));
|
||||
if (!base->refc) {
|
||||
igloo_thread_mutex_unlock(&(base->lock));
|
||||
return NULL;
|
||||
}
|
||||
ret = base->name;
|
||||
igloo_thread_mutex_unlock(&(base->lock));
|
||||
|
||||
@ -176,6 +235,10 @@ igloo_ro_t igloo_ro_get_associated(igloo_ro_t self)
|
||||
return igloo_RO_NULL;
|
||||
|
||||
igloo_thread_mutex_lock(&(base->lock));
|
||||
if (!base->refc) {
|
||||
igloo_thread_mutex_unlock(&(base->lock));
|
||||
return igloo_RO_NULL;
|
||||
}
|
||||
ret = base->associated;
|
||||
if (!igloo_RO_IS_NULL(ret)) {
|
||||
if (igloo_ro_ref(ret) != 0) {
|
||||
@ -208,6 +271,11 @@ int igloo_ro_set_associated(igloo_ro_t self, igloo_ro_t associated)
|
||||
}
|
||||
|
||||
igloo_thread_mutex_lock(&(base->lock));
|
||||
if (!base->refc) {
|
||||
igloo_ro_unref(associated);
|
||||
igloo_thread_mutex_unlock(&(base->lock));
|
||||
return -1;
|
||||
}
|
||||
old = base->associated;
|
||||
base->associated = associated;
|
||||
igloo_thread_mutex_unlock(&(base->lock));
|
||||
|
Loading…
Reference in New Issue
Block a user