]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Rewrite reference counting in isc_mem to use isc_refcount API
authorOndřej Surý <ondrej@sury.org>
Thu, 24 May 2018 12:43:25 +0000 (14:43 +0200)
committerOndřej Surý <ondrej@sury.org>
Tue, 28 Aug 2018 10:15:39 +0000 (12:15 +0200)
lib/isc/mem.c

index aa3b900d6cc66fd9200e2c14774c68a3e31ed27c..99a53ed88dd834209b65f5f4c16f57e487d3a364 100644 (file)
@@ -27,6 +27,7 @@
 #include <isc/mem.h>
 #include <isc/msgs.h>
 #include <isc/once.h>
+#include <isc/refcount.h>
 #include <isc/string.h>
 #include <isc/mutex.h>
 #include <isc/print.h>
@@ -128,7 +129,7 @@ struct isc__mem {
        size_t                  max_size;
        bool            checkfree;
        struct stats *          stats;
-       unsigned int            references;
+       isc_refcount_t          references;
        char                    name[16];
        void *                  tag;
        size_t                  quota;
@@ -905,7 +906,7 @@ isc_mem_createx2(size_t init_max_size, size_t target_size,
        else
                ctx->max_size = init_max_size;
        ctx->flags = flags;
-       ctx->references = 1;
+       isc_refcount_init(&ctx->references, 1);
        memset(ctx->name, 0, sizeof(ctx->name));
        ctx->tag = NULL;
        ctx->quota = 0;
@@ -1048,7 +1049,7 @@ destroy(isc__mem_t *ctx) {
                ctx->malloced -= DEBUG_TABLE_COUNT * sizeof(debuglist_t);
        }
 #endif
-       INSIST(ctx->references == 0);
+       isc_refcount_destroy(&ctx->references);
 
        if (ctx->checkfree) {
                for (i = 0; i <= ctx->max_size; i++) {
@@ -1094,13 +1095,12 @@ destroy(isc__mem_t *ctx) {
 void
 isc__mem_attach(isc_mem_t *source0, isc_mem_t **targetp) {
        isc__mem_t *source = (isc__mem_t *)source0;
+       int_fast32_t refs;
 
        REQUIRE(VALID_CONTEXT(source));
        REQUIRE(targetp != NULL && *targetp == NULL);
 
-       MCTXLOCK(source, &source->lock);
-       source->references++;
-       MCTXUNLOCK(source, &source->lock);
+       isc_refcount_increment(&source->references, &refs);
 
        *targetp = (isc_mem_t *)source;
 }
@@ -1108,21 +1108,17 @@ isc__mem_attach(isc_mem_t *source0, isc_mem_t **targetp) {
 void
 isc__mem_detach(isc_mem_t **ctxp) {
        isc__mem_t *ctx;
-       bool want_destroy = false;
+       int_fast32_t refs;
 
        REQUIRE(ctxp != NULL);
        ctx = (isc__mem_t *)*ctxp;
        REQUIRE(VALID_CONTEXT(ctx));
 
-       MCTXLOCK(ctx, &ctx->lock);
-       INSIST(ctx->references > 0);
-       ctx->references--;
-       if (ctx->references == 0)
-               want_destroy = true;
-       MCTXUNLOCK(ctx, &ctx->lock);
+       isc_refcount_decrement(&ctx->references, &refs);
 
-       if (want_destroy)
+       if (refs == 0) {
                destroy(ctx);
+       }
 
        *ctxp = NULL;
 }
@@ -1140,9 +1136,9 @@ isc__mem_detach(isc_mem_t **ctxp) {
 void
 isc___mem_putanddetach(isc_mem_t **ctxp, void *ptr, size_t size FLARG) {
        isc__mem_t *ctx;
-       bool want_destroy = false;
        size_info *si;
        size_t oldsize;
+       int_fast32_t refs;
 
        REQUIRE(ctxp != NULL);
        ctx = (isc__mem_t *)*ctxp;
@@ -1167,13 +1163,11 @@ isc___mem_putanddetach(isc_mem_t **ctxp, void *ptr, size_t size FLARG) {
                }
                isc__mem_free((isc_mem_t *)ctx, ptr FLARG_PASS);
 
-               MCTXLOCK(ctx, &ctx->lock);
-               ctx->references--;
-               if (ctx->references == 0)
-                       want_destroy = true;
-               MCTXUNLOCK(ctx, &ctx->lock);
-               if (want_destroy)
+               isc_refcount_decrement(&ctx->references, &refs);
+
+               if (refs == 0) {
                        destroy(ctx);
+               }
 
                return;
        }
@@ -1188,21 +1182,19 @@ isc___mem_putanddetach(isc_mem_t **ctxp, void *ptr, size_t size FLARG) {
                mem_putstats(ctx, ptr, size);
                mem_put(ctx, ptr, size);
        }
-
-       INSIST(ctx->references > 0);
-       ctx->references--;
-       if (ctx->references == 0)
-               want_destroy = true;
-
        MCTXUNLOCK(ctx, &ctx->lock);
 
-       if (want_destroy)
+       isc_refcount_decrement(&ctx->references, &refs);
+
+       if (refs == 0) {
                destroy(ctx);
+       }
 }
 
 void
 isc__mem_destroy(isc_mem_t **ctxp) {
        isc__mem_t *ctx;
+       int_fast32_t refs;
 
        /*
         * This routine provides legacy support for callers who use mctxs
@@ -1213,15 +1205,13 @@ isc__mem_destroy(isc_mem_t **ctxp) {
        ctx = (isc__mem_t *)*ctxp;
        REQUIRE(VALID_CONTEXT(ctx));
 
-       MCTXLOCK(ctx, &ctx->lock);
+       isc_refcount_decrement(&ctx->references, &refs);
 #if ISC_MEM_TRACKLINES
-       if (ctx->references != 1)
+       if (refs >= 1) {
                print_active(ctx, stderr);
+       }
 #endif
-       REQUIRE(ctx->references == 1);
-       ctx->references--;
-       MCTXUNLOCK(ctx, &ctx->lock);
-
+       isc_refcount_destroy(&ctx->references);
        destroy(ctx);
 
        *ctxp = NULL;
@@ -2270,10 +2260,10 @@ print_contexts(FILE *file) {
             ctx != NULL;
             ctx = ISC_LIST_NEXT(ctx, link))
        {
-               fprintf(file, "context: %p (%s): %u references\n",
+               fprintf(file, "context: %p (%s): %" PRIdFAST32 " references\n",
                        ctx,
                        ctx->name[0] == 0 ? "<unknown>" : ctx->name,
-                       ctx->references);
+                       isc_refcount_current(&ctx->references));
                print_active(ctx, file);
        }
        fflush(file);
@@ -2315,15 +2305,7 @@ isc_mem_checkdestroyed(FILE *file) {
 unsigned int
 isc_mem_references(isc_mem_t *ctx0) {
        isc__mem_t *ctx = (isc__mem_t *)ctx0;
-       unsigned int references;
-
-       REQUIRE(VALID_CONTEXT(ctx));
-
-       MCTXLOCK(ctx, &ctx->lock);
-       references = ctx->references;
-       MCTXUNLOCK(ctx, &ctx->lock);
-
-       return (references);
+       return (isc_refcount_current(&ctx->references));
 }
 
 typedef struct summarystat {
@@ -2370,7 +2352,8 @@ xml_renderctx(isc__mem_t *ctx, summarystat_t *summary,
        }
 #endif
        TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "references"));
-       TRY0(xmlTextWriterWriteFormatString(writer, "%d", ctx->references));
+       TRY0(xmlTextWriterWriteFormatString(writer, "%" PRIdFAST32,
+                                           isc_refcount_current(&ctx->references)));
        TRY0(xmlTextWriterEndElement(writer)); /* references */
 
        summary->total += ctx->total;
@@ -2570,7 +2553,7 @@ json_renderctx(isc__mem_t *ctx, summarystat_t *summary, json_object *array) {
                json_object_object_add(ctxobj, "name", obj);
        }
 
-       obj = json_object_new_int64(ctx->references);
+       obj = json_object_new_int64(isc_refcount_current(&ctx->references));
        CHECKMEM(obj);
        json_object_object_add(ctxobj, "references", obj);