tal: add del_destructor().
authorRusty Russell <rusty@rustcorp.com.au>
Mon, 3 Dec 2012 08:59:38 +0000 (19:29 +1030)
committerRusty Russell <rusty@rustcorp.com.au>
Mon, 3 Dec 2012 08:59:38 +0000 (19:29 +1030)
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ccan/tal/tal.c
ccan/tal/tal.h
ccan/tal/test/run-destructor.c

index 8245aba95028d90a007eb0c4b6edf83284d9b984..194e74c68afc8d9662b00a2924a2b2cb1da28fb6 100644 (file)
@@ -258,6 +258,28 @@ static struct destructor *add_destructor_property(struct tal_hdr *t,
        return prop;
 }
 
+static bool del_destructor_property(struct tal_hdr *t,
+                                   void (*destroy)(void *))
+{
+        struct prop_hdr **p;
+
+        for (p = (struct prop_hdr **)&t->prop; *p; p = &(*p)->next) {
+               struct destructor *d;
+
+                if (is_literal(*p))
+                       break;
+                if ((*p)->type != DESTRUCTOR)
+                       continue;
+               d = (struct destructor *)*p;
+               if (d->destroy == destroy) {
+                       *p = (*p)->next;
+                       freefn(d);
+                       return true;
+               }
+        }
+        return false;
+}
+
 static struct name *add_name_property(struct tal_hdr *t, const char *name)
 {
        struct name *prop;
@@ -399,6 +421,11 @@ bool tal_add_destructor_(tal_t *ctx, void (*destroy)(void *me))
         return add_destructor_property(debug_tal(to_tal_hdr(ctx)), destroy);
 }
 
+bool tal_del_destructor_(tal_t *ctx, void (*destroy)(void *me))
+{
+        return del_destructor_property(debug_tal(to_tal_hdr(ctx)), destroy);
+}
+
 bool tal_set_name_(tal_t *ctx, const char *name, bool literal)
 {
         struct tal_hdr *t = debug_tal(to_tal_hdr(ctx));
index 42245f68660277c990561502f50b00f94297bcb5..7efc824ab9da37b806f159d7107caf57bef66c18 100644 (file)
@@ -130,6 +130,17 @@ void *tal_free(const tal_t *p);
 #define tal_add_destructor(ptr, function)                                    \
        tal_add_destructor_((ptr), typesafe_cb(void, void *, (function), (ptr)))
 
+/**
+ * tal_del_destructor - remove a destructor callback function.
+ * @ptr: The tal allocated object.
+ * @function: the function to call before it's freed.
+ *
+ * If @function has not been successfully added as a destructor, this returns
+ * false.
+ */
+#define tal_del_destructor(ptr, function)                                    \
+       tal_del_destructor_((ptr), typesafe_cb(void, void *, (function), (ptr)))
+
 /**
  * tal_set_name - attach a name to a tal pointer.
  * @ptr: The tal allocated object.
@@ -324,5 +335,6 @@ tal_t *tal_steal_(const tal_t *new_parent, const tal_t *t);
 bool tal_resize_(tal_t **ctxp, size_t size);
 
 bool tal_add_destructor_(tal_t *ctx, void (*destroy)(void *me));
+bool tal_del_destructor_(tal_t *ctx, void (*destroy)(void *me));
 
 #endif /* CCAN_TAL_H */
index 9d3a94e60b323a188b3f3f3bcb5d859ad942591f..30c5136b5b4452aba1fe7f49cb5799f60cd88a80 100644 (file)
@@ -33,16 +33,26 @@ int main(void)
 {
        char *child2;
 
-       plan_tests(12);
+       plan_tests(18);
 
+       destroy_count = 0;
        parent = tal(NULL, char);
        child = tal(parent, char);
        ok1(tal_add_destructor(parent, destroy_parent));
        ok1(tal_add_destructor(child, destroy_child));
-
        tal_free(parent);
        ok1(destroy_count == 2);
 
+       destroy_count = 0;
+       parent = tal(NULL, char);
+       child = tal(parent, char);
+       ok1(tal_add_destructor(parent, destroy_parent));
+       ok1(tal_add_destructor(child, destroy_child));
+       ok1(tal_del_destructor(child, destroy_child));
+       tal_free(parent);
+       ok1(destroy_count == 1);
+
+       destroy_count = 0;
        parent = tal(NULL, char);
        child = tal(parent, char);
        child2 = tal(parent, char);
@@ -51,7 +61,7 @@ int main(void)
        ok1(tal_add_destructor(child, destroy_inc));
        ok1(tal_add_destructor(child2, destroy_inc));
        tal_free(parent);
-       ok1(destroy_count == 6);
+       ok1(destroy_count == 4);
 
        return exit_status();
 }