Browse Source

tal: add del_destructor().

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Rusty Russell 13 years ago
parent
commit
ca6991d861
3 changed files with 52 additions and 3 deletions
  1. 27 0
      ccan/tal/tal.c
  2. 12 0
      ccan/tal/tal.h
  3. 13 3
      ccan/tal/test/run-destructor.c

+ 27 - 0
ccan/tal/tal.c

@@ -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));

+ 12 - 0
ccan/tal/tal.h

@@ -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 */

+ 13 - 3
ccan/tal/test/run-destructor.c

@@ -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();
 }