Remove un-thread safe shared reference count.

This commit is contained in:
Danila Fedorin 2018-04-24 15:08:39 -07:00
parent 4dcf422757
commit ee76d39f38
2 changed files with 18 additions and 14 deletions

View File

@ -34,7 +34,11 @@ struct libab_ref_s {
/** /**
* Whether this reference is a strong reference. * Whether this reference is a strong reference.
*/ */
int strong; unsigned int strong:1;
/**
* Whether this reference is a NULL reference.
*/
unsigned int null:1;
/** /**
* The reference count struct keeping track * The reference count struct keeping track
* of how many references are pointing to the value. * of how many references are pointing to the value.

View File

@ -5,6 +5,7 @@
libab_result libab_ref_new(libab_ref* ref, void* data, libab_result libab_ref_new(libab_ref* ref, void* data,
void (*free_func)(void* data)) { void (*free_func)(void* data)) {
libab_result result = LIBAB_SUCCESS; libab_result result = LIBAB_SUCCESS;
ref->null = 0;
ref->strong = 1; ref->strong = 1;
ref->data = data; ref->data = data;
if ((ref->count = malloc(sizeof(*(ref->count))))) { if ((ref->count = malloc(sizeof(*(ref->count))))) {
@ -16,13 +17,8 @@ libab_result libab_ref_new(libab_ref* ref, void* data,
return result; return result;
} }
static libab_ref_count null_count = {NULL, 0, 1};
void libab_ref_null(libab_ref* ref) { void libab_ref_null(libab_ref* ref) {
ref->strong = 0; ref->null = 1;
ref->data = NULL;
ref->count = &null_count;
null_count.weak++;
} }
void _libab_ref_changed(libab_ref* ref) { void _libab_ref_changed(libab_ref* ref) {
@ -38,7 +34,7 @@ void _libab_ref_changed(libab_ref* ref) {
} }
void libab_ref_weaken(libab_ref* ref) { void libab_ref_weaken(libab_ref* ref) {
if (ref->strong) { if (!ref->null && ref->strong) {
ref->count->strong--; ref->count->strong--;
ref->strong = 0; ref->strong = 0;
_libab_ref_changed(ref); _libab_ref_changed(ref);
@ -46,14 +42,18 @@ void libab_ref_weaken(libab_ref* ref) {
} }
void libab_ref_free(libab_ref* ref) { void libab_ref_free(libab_ref* ref) {
ref->count->strong -= ref->strong; if(!ref->null) {
ref->count->weak--; ref->count->strong -= ref->strong;
_libab_ref_changed(ref); ref->count->weak--;
_libab_ref_changed(ref);
}
} }
void libab_ref_copy(const libab_ref* ref, libab_ref* into) { void libab_ref_copy(const libab_ref* ref, libab_ref* into) {
ref->count->strong++; if(!ref->null) {
ref->count->weak++; ref->count->strong++;
ref->count->weak++;
}
memcpy(into, ref, sizeof(*ref)); memcpy(into, ref, sizeof(*ref));
} }
@ -61,7 +61,7 @@ void libab_ref_data_free(void* data) { free(data); }
void* libab_ref_get(const libab_ref* ref) { void* libab_ref_get(const libab_ref* ref) {
void* to_return = NULL; void* to_return = NULL;
if (ref->count->strong > 0) { if (!ref->null && ref->count->strong > 0) {
to_return = ref->data; to_return = ref->data;
} }
return to_return; return to_return;