2018-03-30 22:37:30 -07:00
|
|
|
#ifndef LIBABACUS_REFCOUNT_H
|
|
|
|
#define LIBABACUS_REFCOUNT_H
|
|
|
|
|
|
|
|
#include "result.h"
|
2018-08-11 18:22:18 -07:00
|
|
|
#include "gc_functions.h"
|
2018-08-11 01:29:48 -07:00
|
|
|
|
2018-03-30 22:37:30 -07:00
|
|
|
/**
|
|
|
|
* A struct for holding
|
|
|
|
* the number of references
|
|
|
|
* to a value, as well as the function required
|
|
|
|
* to free the value.
|
|
|
|
*/
|
|
|
|
struct libab_ref_count_s {
|
2018-08-11 01:29:48 -07:00
|
|
|
/**
|
|
|
|
* The value this reference holds.
|
|
|
|
*/
|
|
|
|
void* data;
|
2018-03-30 22:37:30 -07:00
|
|
|
/**
|
|
|
|
* The fucntion to free the value.
|
|
|
|
* Can be NULL for no-op.
|
|
|
|
*/
|
|
|
|
void (*free_func)(void* data);
|
|
|
|
/**
|
|
|
|
* The number of references that
|
|
|
|
* prevent the deallocation of the value.
|
|
|
|
*/
|
|
|
|
int strong;
|
|
|
|
/**
|
|
|
|
* The number of references
|
|
|
|
* that still exist, even to a freed instance.
|
|
|
|
*/
|
|
|
|
int weak;
|
2018-08-11 01:29:48 -07:00
|
|
|
/**
|
|
|
|
* The number of outside references.
|
|
|
|
* This is used for garbage collection.
|
|
|
|
*/
|
|
|
|
int gc;
|
|
|
|
/**
|
|
|
|
* Previous pointer for garbage collection
|
|
|
|
* linked list.
|
|
|
|
*/
|
|
|
|
struct libab_ref_count_s* prev;
|
|
|
|
/**
|
|
|
|
* Next pointer for garbage collection
|
|
|
|
* linked list.
|
|
|
|
*/
|
|
|
|
struct libab_ref_count_s* next;
|
|
|
|
/**
|
|
|
|
* Function used to visit child containers,
|
|
|
|
* used by GC.
|
|
|
|
*/
|
|
|
|
libab_visit_function_ptr visit_children;
|
|
|
|
};
|
|
|
|
|
2018-03-30 22:37:30 -07:00
|
|
|
/**
|
|
|
|
* A reference to a value.
|
|
|
|
*/
|
|
|
|
struct libab_ref_s {
|
|
|
|
/**
|
|
|
|
* Whether this reference is a strong reference.
|
|
|
|
*/
|
2018-05-17 14:53:48 -07:00
|
|
|
unsigned int strong : 1;
|
2018-04-24 15:08:39 -07:00
|
|
|
/**
|
|
|
|
* Whether this reference is a NULL reference.
|
|
|
|
*/
|
2018-05-17 14:53:48 -07:00
|
|
|
unsigned int null : 1;
|
2018-03-30 22:37:30 -07:00
|
|
|
/**
|
|
|
|
* The reference count struct keeping track
|
|
|
|
* of how many references are pointing to the value.
|
|
|
|
*/
|
|
|
|
struct libab_ref_count_s* count;
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef struct libab_ref_s libab_ref;
|
|
|
|
typedef struct libab_ref_count_s libab_ref_count;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates a new referene, using the given data and free function.
|
|
|
|
* @param ref the reference to initialize with the given data.
|
|
|
|
* @param data the data to reference count.
|
2018-04-21 14:09:01 -07:00
|
|
|
* @param free_func the function to use to realease the data when refcount
|
|
|
|
* reaches 0.
|
2018-03-30 22:37:30 -07:00
|
|
|
* @return the result of the construction of the reference.
|
|
|
|
*/
|
2018-04-21 14:09:01 -07:00
|
|
|
libab_result libab_ref_new(libab_ref* ref, void* data,
|
|
|
|
void (*free_func)(void* data));
|
2018-04-06 23:53:40 -07:00
|
|
|
/**
|
|
|
|
* Creates a reference to NULL. This does
|
|
|
|
* not require a memory allocation.
|
|
|
|
* @param ref the reference to initialize with null.
|
|
|
|
*/
|
|
|
|
void libab_ref_null(libab_ref* ref);
|
2018-03-30 22:37:30 -07:00
|
|
|
/**
|
|
|
|
* Turns the given reference into a weak reference,
|
|
|
|
* making it not keep the data allocated.
|
|
|
|
*/
|
|
|
|
void libab_ref_weaken(libab_ref* ref);
|
|
|
|
/**
|
|
|
|
* Releases this particular reference to the data.
|
|
|
|
* This doesn't necessarily free the underlying data.
|
|
|
|
*/
|
|
|
|
void libab_ref_free(libab_ref* ref);
|
|
|
|
/**
|
|
|
|
* Copies this reference, thereby increasing the reference count.
|
|
|
|
*/
|
2018-03-31 20:44:01 -07:00
|
|
|
void libab_ref_copy(const libab_ref* ref, libab_ref* into);
|
2018-05-14 19:16:42 -07:00
|
|
|
/**
|
|
|
|
* Swaps the contents of two references.
|
|
|
|
*/
|
|
|
|
void libab_ref_swap(libab_ref* left, libab_ref* right);
|
2018-04-21 17:05:51 -07:00
|
|
|
/**
|
|
|
|
* Function that can be passed in to refcount to simply use free
|
|
|
|
* when the refcount reaches 0.
|
|
|
|
*/
|
|
|
|
void libab_ref_data_free(void*);
|
2018-03-30 22:37:30 -07:00
|
|
|
/**
|
|
|
|
* Gets the value of the reference.
|
|
|
|
*/
|
2018-03-31 20:44:01 -07:00
|
|
|
void* libab_ref_get(const libab_ref* ref);
|
2018-03-30 22:37:30 -07:00
|
|
|
|
|
|
|
#endif
|