2018-03-30 22:37:30 -07:00
|
|
|
#include "refcount.h"
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
2018-04-21 14:09:01 -07:00
|
|
|
libab_result libab_ref_new(libab_ref* ref, void* data,
|
|
|
|
void (*free_func)(void* data)) {
|
2018-03-30 22:37:30 -07:00
|
|
|
libab_result result = LIBAB_SUCCESS;
|
2018-04-24 15:08:39 -07:00
|
|
|
ref->null = 0;
|
2018-03-30 22:37:30 -07:00
|
|
|
ref->strong = 1;
|
|
|
|
ref->data = data;
|
2018-04-21 14:09:01 -07:00
|
|
|
if ((ref->count = malloc(sizeof(*(ref->count))))) {
|
2018-03-30 22:37:30 -07:00
|
|
|
ref->count->strong = ref->count->weak = 1;
|
|
|
|
ref->count->free_func = free_func;
|
|
|
|
} else {
|
|
|
|
result = LIBAB_MALLOC;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2018-04-06 23:53:40 -07:00
|
|
|
void libab_ref_null(libab_ref* ref) {
|
2018-04-24 15:08:39 -07:00
|
|
|
ref->null = 1;
|
2018-04-06 23:53:40 -07:00
|
|
|
}
|
|
|
|
|
2018-03-30 22:37:30 -07:00
|
|
|
void _libab_ref_changed(libab_ref* ref) {
|
2018-04-21 14:09:01 -07:00
|
|
|
if (ref->count->strong == 0) {
|
2018-03-30 22:37:30 -07:00
|
|
|
ref->count->strong--;
|
2018-04-21 14:09:01 -07:00
|
|
|
if (ref->count->free_func) {
|
2018-03-30 22:37:30 -07:00
|
|
|
ref->count->free_func(ref->data);
|
|
|
|
}
|
|
|
|
}
|
2018-04-21 14:09:01 -07:00
|
|
|
if (ref->count->weak == 0) {
|
2018-03-30 22:37:30 -07:00
|
|
|
free(ref->count);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void libab_ref_weaken(libab_ref* ref) {
|
2018-04-24 15:08:39 -07:00
|
|
|
if (!ref->null && ref->strong) {
|
2018-03-30 22:37:30 -07:00
|
|
|
ref->count->strong--;
|
|
|
|
ref->strong = 0;
|
|
|
|
_libab_ref_changed(ref);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void libab_ref_free(libab_ref* ref) {
|
2018-04-24 15:08:39 -07:00
|
|
|
if(!ref->null) {
|
|
|
|
ref->count->strong -= ref->strong;
|
|
|
|
ref->count->weak--;
|
|
|
|
_libab_ref_changed(ref);
|
|
|
|
}
|
2018-03-30 22:37:30 -07:00
|
|
|
}
|
|
|
|
|
2018-03-31 20:44:01 -07:00
|
|
|
void libab_ref_copy(const libab_ref* ref, libab_ref* into) {
|
2018-04-24 15:08:39 -07:00
|
|
|
if(!ref->null) {
|
|
|
|
ref->count->strong++;
|
|
|
|
ref->count->weak++;
|
|
|
|
}
|
2018-03-30 22:37:30 -07:00
|
|
|
memcpy(into, ref, sizeof(*ref));
|
|
|
|
}
|
|
|
|
|
2018-04-21 17:05:51 -07:00
|
|
|
void libab_ref_data_free(void* data) { free(data); }
|
|
|
|
|
2018-03-31 20:44:01 -07:00
|
|
|
void* libab_ref_get(const libab_ref* ref) {
|
2018-03-30 22:37:30 -07:00
|
|
|
void* to_return = NULL;
|
2018-04-24 15:08:39 -07:00
|
|
|
if (!ref->null && ref->count->strong > 0) {
|
2018-03-30 22:37:30 -07:00
|
|
|
to_return = ref->data;
|
|
|
|
}
|
|
|
|
return to_return;
|
|
|
|
}
|