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 { | typedef struct RefcountContext { | ||||||
|     size_t entry_offset; //!< Offset to the #RefcountEntry member. |     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 |     refcount_held_refs_callback_t | ||||||
|         held_refs_callback; //!< Callback to list an object's held references. |         held_refs_callback; //!< Callback to list an object's held references. | ||||||
|     refcount_destroy_callback_t |     refcount_destroy_callback_t | ||||||
| @ -75,7 +77,7 @@ typedef struct RefcountContext { | |||||||
| extern RefcountContext *refcount_default_context; | extern RefcountContext *refcount_default_context; | ||||||
|  |  | ||||||
| RefcountContext * | 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_held_refs_callback_t held_refs_callback, | ||||||
|                       refcount_destroy_callback_t destroy_callback, |                       refcount_destroy_callback_t destroy_callback, | ||||||
|                       void *user_data, const RefcountAllocator *alloc); |                       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 |  * @return The new context, or NULL in the case of an error | ||||||
|  */ |  */ | ||||||
| RefcountContext * | 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_held_refs_callback_t held_refs_callback, | ||||||
|                       refcount_destroy_callback_t destroy_callback, |                       refcount_destroy_callback_t destroy_callback, | ||||||
|                       void *user_data, const RefcountAllocator *alloc) { |                       void *user_data, const RefcountAllocator *alloc) { | ||||||
| @ -82,6 +82,7 @@ refcount_make_context(size_t entry_offset, | |||||||
|     } |     } | ||||||
| #endif | #endif | ||||||
|     ctx->entry_offset = entry_offset; |     ctx->entry_offset = entry_offset; | ||||||
|  |     ctx->void_val = void_val; | ||||||
|     ctx->held_refs_callback = held_refs_callback; |     ctx->held_refs_callback = held_refs_callback; | ||||||
|     ctx->destroy_callback = destroy_callback; |     ctx->destroy_callback = destroy_callback; | ||||||
|     ctx->user_data = user_data; |     ctx->user_data = user_data; | ||||||
| @ -355,7 +356,7 @@ end: | |||||||
|  */ |  */ | ||||||
| void *refcount_context_ref(const RefcountContext *ctx, void *obj) { | void *refcount_context_ref(const RefcountContext *ctx, void *obj) { | ||||||
|     if (!obj) { |     if (!obj) { | ||||||
|         return NULL; |         return ctx->void_val; | ||||||
|     } |     } | ||||||
|     if (!lock_entry_mtx(ENTRY)) { |     if (!lock_entry_mtx(ENTRY)) { | ||||||
|         return obj; |         return obj; | ||||||
| @ -419,7 +420,7 @@ static void remove_gc_root(RefcountContext *ctx, void *obj) { | |||||||
| static void *unref_to_queue(RefcountContext *ctx, void *obj, | static void *unref_to_queue(RefcountContext *ctx, void *obj, | ||||||
|                             RefcountList **queue) { |                             RefcountList **queue) { | ||||||
|     if (!obj) { |     if (!obj) { | ||||||
|         return NULL; |         return ctx->void_val; | ||||||
|     } else if (ENTRY->is_static) { |     } else if (ENTRY->is_static) { | ||||||
|         return obj; |         return obj; | ||||||
|     } |     } | ||||||
| @ -437,7 +438,7 @@ static void *unref_to_queue(RefcountContext *ctx, void *obj, | |||||||
|             *queue = refcount_list_push_full(*queue, obj, &ctx->alloc); |             *queue = refcount_list_push_full(*queue, obj, &ctx->alloc); | ||||||
|         } |         } | ||||||
|         unlock_entry_mtx(ENTRY); |         unlock_entry_mtx(ENTRY); | ||||||
|         return NULL; |         return ctx->void_val; | ||||||
|     } else { |     } else { | ||||||
|         --ENTRY->impl.counted.ref_count; |         --ENTRY->impl.counted.ref_count; | ||||||
|         track_gc_root(ctx, obj); |         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) { | void *refcount_context_unref(RefcountContext *ctx, void *obj) { | ||||||
|     if (!obj) { |     if (!obj) { | ||||||
|         return NULL; |         return ctx->void_val; | ||||||
|     } |     } | ||||||
|     RefcountList *queue = NULL; |     RefcountList *queue = NULL; | ||||||
|     void *retval = unref_to_queue(ctx, obj, &queue); |     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}; |     struct ContextAndFlag ctx_and_flag = {.should_be_doing_gc = false}; | ||||||
|  |  | ||||||
|     RefcountContext *c = refcount_make_context( |     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, &COUNTING_ALLOCATOR); | ||||||
|  |  | ||||||
|     ctx_and_flag.ctx = c; |     ctx_and_flag.ctx = c; | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user