Add destructors
This commit is contained in:
		| @ -80,8 +80,8 @@ refcount_make_context(size_t entry_offset, | ||||
| void refcount_context_destroy(RefcountContext *ctx); | ||||
|  | ||||
| /** | ||||
|  * Structure holding the required information for a weak reference. That is, a | ||||
|  * reference that does not prevent an object from being de-allocated. | ||||
|  * Opaque structure holding the required information for a weak reference. That | ||||
|  * is, a reference that does not prevent an object from being de-allocated. | ||||
|  */ | ||||
| typedef struct RefcountWeakref { | ||||
| #ifdef REFCOUNT_HAS_THREADS | ||||
| @ -94,8 +94,18 @@ typedef struct RefcountWeakref { | ||||
| } RefcountWeakref; | ||||
|  | ||||
| /** | ||||
|  * Opaque struct holding reference data for an object. This should be included | ||||
|  * as a non-pointer member of the struct you are trying to track, e.g. | ||||
|  * Destructor callback type. Called before and object is freed after having its | ||||
|  * reference count drop to zero. This function can prevent the given object | ||||
|  * from being freed by increasing its reference count. | ||||
|  * @param obj The object being destroyed | ||||
|  * @param user_data Arbitrary user_provided data | ||||
|  */ | ||||
| typedef void (*refcount_destructor_callback_t)(void *obj, void *user_data); | ||||
|  | ||||
| /** | ||||
|  * Opaque struct holding reference data for an object. This should be | ||||
|  * included as a non-pointer member of the struct you are trying to track, | ||||
|  * e.g. | ||||
|  * @code | ||||
|  * struct A { | ||||
|  *     int my_num; | ||||
| @ -106,7 +116,8 @@ typedef struct RefcountWeakref { | ||||
|  */ | ||||
| typedef struct RefcountEntry { | ||||
|     bool is_static; //!< Whether the object is static. | ||||
|     RefcountWeakref *weak_ref; //<! Weakref for this entry. | ||||
|     RefcountWeakref *weak_ref; //!< Weakref for this entry. | ||||
|     HTTable *destructors; //!< Hash table of object destructors. | ||||
|     union { | ||||
|         struct { | ||||
|             uint64_t ref_count; //!< The object's reference count. | ||||
| @ -226,6 +237,14 @@ static inline RefcountWeakref *refcount_context_weaken(RefcountContext *ctx, | ||||
|     return wr; | ||||
| } | ||||
|  | ||||
| bool refcount_context_add_destructor(const RefcountContext *ctx, void *obj, | ||||
|                                      void *key, | ||||
|                                      refcount_destructor_callback_t callback, | ||||
|                                      void *user_data); | ||||
|  | ||||
| bool refcount_context_remove_destructor(const RefcountContext *ctx, void *obj, | ||||
|                                         void *key); | ||||
|  | ||||
| /** | ||||
|  * Same as #refcount_context_is_static, but only operates on the global | ||||
|  * context. | ||||
| @ -367,7 +386,7 @@ static inline void *refcount_strengthen(RefcountWeakref *wr) { | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Same as #refcount_context_weaken, but operates ojn the global context. | ||||
|  * Same as #refcount_context_weaken, but operates on the global context. | ||||
|  * @param obj The object to create a weak reference for then unref | ||||
|  * @return The newly created weak reference, or NULL if an allocation error | ||||
|  * occurred. In this case the object is not unrefed. | ||||
| @ -376,6 +395,35 @@ static inline RefcountWeakref *refcount_weaken(void *obj) { | ||||
|     return refcount_context_weaken(refcount_default_context, obj); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Same as #refcount_context_add_destructor, but operates on the global context. | ||||
|  * @param obj The object onto which to register the destructor | ||||
|  * @param key An arbitrary value that can be later used to unregister the | ||||
|  * destructor | ||||
|  * @param callback The destructor itself | ||||
|  * @param user_data Extra data to pass to the destructor | ||||
|  * @return True on success, false on failure. On failure, nothing is registered. | ||||
|  */ | ||||
| static inline bool | ||||
| refcount_add_destructor(void *obj, void *key, | ||||
|                         refcount_destructor_callback_t callback, | ||||
|                         void *user_data) { | ||||
|     return refcount_context_add_destructor(refcount_default_context, obj, key, | ||||
|                                            callback, user_data); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Same as #refcount_context_remove_destructor, but operates on the global | ||||
|  * context. | ||||
|  * @param obj The object for which to unregister the destructor | ||||
|  * @param key The destructors key | ||||
|  * @return True on success, false on error. On error, nothing is unregistered. | ||||
|  */ | ||||
| static inline bool refcount_remove_destructor(void *obj, void *key) { | ||||
|     return refcount_context_remove_destructor(refcount_default_context, obj, | ||||
|                                               key); | ||||
| } | ||||
|  | ||||
| #ifdef __cplusplus | ||||
| } | ||||
| #endif | ||||
|  | ||||
		Reference in New Issue
	
	Block a user