Add void_obj option
This commit is contained in:
@ -51,6 +51,8 @@ typedef void (*refcount_destroy_callback_t)(void *obj, void *user_data);
|
||||
*/
|
||||
typedef struct RefcountContext {
|
||||
size_t entry_offset; //!< Offset to the #RefcountEntry member.
|
||||
void *void_val; //!< Value returned by #refcount_context_unref when a
|
||||
//!< reference count falls to 0.
|
||||
refcount_held_refs_callback_t
|
||||
held_refs_callback; //!< Callback to list an object's held references.
|
||||
refcount_destroy_callback_t
|
||||
@ -75,7 +77,7 @@ typedef struct RefcountContext {
|
||||
extern RefcountContext *refcount_default_context;
|
||||
|
||||
RefcountContext *
|
||||
refcount_make_context(size_t entry_offset,
|
||||
refcount_make_context(size_t entry_offset, void *void_val,
|
||||
refcount_held_refs_callback_t held_refs_callback,
|
||||
refcount_destroy_callback_t destroy_callback,
|
||||
void *user_data, const RefcountAllocator *alloc);
|
||||
|
@ -59,7 +59,7 @@ RefcountContext *refcount_default_context = NULL;
|
||||
* @return The new context, or NULL in the case of an error
|
||||
*/
|
||||
RefcountContext *
|
||||
refcount_make_context(size_t entry_offset,
|
||||
refcount_make_context(size_t entry_offset, void *void_val,
|
||||
refcount_held_refs_callback_t held_refs_callback,
|
||||
refcount_destroy_callback_t destroy_callback,
|
||||
void *user_data, const RefcountAllocator *alloc) {
|
||||
@ -82,6 +82,7 @@ refcount_make_context(size_t entry_offset,
|
||||
}
|
||||
#endif
|
||||
ctx->entry_offset = entry_offset;
|
||||
ctx->void_val = void_val;
|
||||
ctx->held_refs_callback = held_refs_callback;
|
||||
ctx->destroy_callback = destroy_callback;
|
||||
ctx->user_data = user_data;
|
||||
@ -355,7 +356,7 @@ end:
|
||||
*/
|
||||
void *refcount_context_ref(const RefcountContext *ctx, void *obj) {
|
||||
if (!obj) {
|
||||
return NULL;
|
||||
return ctx->void_val;
|
||||
}
|
||||
if (!lock_entry_mtx(ENTRY)) {
|
||||
return obj;
|
||||
@ -419,7 +420,7 @@ static void remove_gc_root(RefcountContext *ctx, void *obj) {
|
||||
static void *unref_to_queue(RefcountContext *ctx, void *obj,
|
||||
RefcountList **queue) {
|
||||
if (!obj) {
|
||||
return NULL;
|
||||
return ctx->void_val;
|
||||
} else if (ENTRY->is_static) {
|
||||
return obj;
|
||||
}
|
||||
@ -437,7 +438,7 @@ static void *unref_to_queue(RefcountContext *ctx, void *obj,
|
||||
*queue = refcount_list_push_full(*queue, obj, &ctx->alloc);
|
||||
}
|
||||
unlock_entry_mtx(ENTRY);
|
||||
return NULL;
|
||||
return ctx->void_val;
|
||||
} else {
|
||||
--ENTRY->impl.counted.ref_count;
|
||||
track_gc_root(ctx, obj);
|
||||
@ -523,7 +524,7 @@ static void process_unref_queue(RefcountContext *ctx, RefcountList *queue,
|
||||
*/
|
||||
void *refcount_context_unref(RefcountContext *ctx, void *obj) {
|
||||
if (!obj) {
|
||||
return NULL;
|
||||
return ctx->void_val;
|
||||
}
|
||||
RefcountList *queue = NULL;
|
||||
void *retval = unref_to_queue(ctx, obj, &queue);
|
||||
|
@ -50,7 +50,7 @@ int main(int argc, const char **argv) {
|
||||
struct ContextAndFlag ctx_and_flag = {.should_be_doing_gc = false};
|
||||
|
||||
RefcountContext *c = refcount_make_context(
|
||||
offsetof(A, refcount), held_refs_callback, destroy_callback,
|
||||
offsetof(A, refcount), NULL, held_refs_callback, destroy_callback,
|
||||
&ctx_and_flag, &COUNTING_ALLOCATOR);
|
||||
|
||||
ctx_and_flag.ctx = c;
|
||||
|
Reference in New Issue
Block a user