]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add extra set of ISC_REFCOUNT_TRACE_{IMPL,DECL} macros
authorOndřej Surý <ondrej@isc.org>
Wed, 5 Oct 2022 09:19:52 +0000 (11:19 +0200)
committerEvan Hunt <each@isc.org>
Wed, 30 Nov 2022 07:57:40 +0000 (23:57 -0800)
The new ISC_REFCOUNT_TRACE_{IMPL,DECL} macros can be used to add a
reference tracing capability to any unit using the reference counting.
It requires a little bit of extra work in each header as you can't have
a define from inside a define (see rpz.h), but it's fairly easy to add
tracing to any struct using reference counting with these macros.

lib/isc/include/isc/refcount.h

index e33cd7df25b70cd7aa0f1ba82b7b47f9d58f4382..80ba888d06d1678f41eef70ece045e13434390d5 100644 (file)
@@ -149,6 +149,53 @@ isc_refcount_decrement(isc_refcount_t *target) {
                ISC_INSIST(_refs > 0);                                \
        } while (0)
 
+#define ISC_REFCOUNT_TRACE_DECL(name)                                         \
+       void name##__ref(name##_t *ptr, const char *func, const char *file,   \
+                        unsigned int line);                                  \
+       void name##__unref(name##_t *ptr, const char *func, const char *file, \
+                          unsigned int line);                                \
+       void name##__attach(name##_t *ptr, name##_t **ptrp, const char *func, \
+                           const char *file, unsigned int line);             \
+       void name##__detach(name##_t **ptrp, const char *func,                \
+                           const char *file, unsigned int line)
+
+#define ISC_REFCOUNT_TRACE_IMPL(name, destroy)                                \
+       void name##__ref(name##_t *ptr, const char *func, const char *file,   \
+                        unsigned int line) {                                 \
+               uint_fast32_t refs;                                           \
+               REQUIRE(ptr != NULL);                                         \
+               refs = isc_refcount_increment(&ptr->references);              \
+               fprintf(stderr,                                               \
+                       "%s:%s:%s:%u:%p->references = %" PRIuFAST32 "\n",     \
+                       __func__, func, file, line, ptr, refs + 1);           \
+       }                                                                     \
+                                                                              \
+       void name##__unref(name##_t *ptr, const char *func, const char *file, \
+                          unsigned int line) {                               \
+               uint_fast32_t refs;                                           \
+               REQUIRE(ptr != NULL);                                         \
+               if ((refs = isc_refcount_decrement(&ptr->references)) == 1) { \
+                       destroy(ptr);                                         \
+               }                                                             \
+               fprintf(stderr,                                               \
+                       "%s:%s:%s:%u:%p->references = %" PRIuFAST32 "\n",     \
+                       __func__, func, file, line, ptr, refs - 1);           \
+       }                                                                     \
+       void name##__attach(name##_t *ptr, name##_t **ptrp, const char *func, \
+                           const char *file, unsigned int line) {            \
+               REQUIRE(ptrp != NULL && *ptrp == NULL);                       \
+               name##__ref(ptr, func, file, line);                           \
+               *ptrp = ptr;                                                  \
+       }                                                                     \
+                                                                              \
+       void name##__detach(name##_t **ptrp, const char *func,                \
+                           const char *file, unsigned int line) {            \
+               REQUIRE(ptrp != NULL && *ptrp != NULL);                       \
+               name##_t *ptr = *ptrp;                                        \
+               *ptrp = NULL;                                                 \
+               name##__unref(ptr, func, file, line);                         \
+       }
+
 #define ISC_REFCOUNT_DECL(name)                             \
        void name##_ref(name##_t *ptr);                     \
        void name##_unref(name##_t *ptr);                   \