* nih/main.h (NihMainLoopFunc): Add delete member.
* nih/main.c (nih_main_loop): Don't run the callback for any function
marked for deletion, instead call nih_free on it.
(nih_main_loop_add_func): Initialise delete to FALSE.
* nih/dbus.c (nih_dbus_release_callback): Add function to mark a
loop function as deleted.
(nih_dbus_setup): and use it as the free function instead of nih_free.
* nih/tests/test_dbus.c (test_connect, test_bus, test_setup): Check
that the loop functions are marked for deletion instead of freed.
* nih/nih_dbus_tool.py (Output.sourceFile): Include limits.h
diff --git a/ChangeLog b/ChangeLog
index 7f09001..7f89d80 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2008-08-12 Casey Dahlin <cdahlin@redhat.com>
+
+ * nih/main.h (NihMainLoopFunc): Add delete member.
+ * nih/main.c (nih_main_loop): Don't run the callback for any function
+ marked for deletion, instead call nih_free on it.
+ (nih_main_loop_add_func): Initialise delete to FALSE.
+ * nih/dbus.c (nih_dbus_release_callback): Add function to mark a
+ loop function as deleted.
+ (nih_dbus_setup): and use it as the free function instead of nih_free.
+ * nih/tests/test_dbus.c (test_connect, test_bus, test_setup): Check
+ that the loop functions are marked for deletion instead of freed.
+
+ * nih/nih_dbus_tool.py (Output.sourceFile): Include limits.h
+
2008-07-02 Scott James Remnant <scott@netsplit.com>
* nih/Makefile.am (test_com_netsplit_Nih_Test_object_SOURCES)
diff --git a/nih/dbus.c b/nih/dbus.c
index 3c55282..814caf4 100644
--- a/nih/dbus.c
+++ b/nih/dbus.c
@@ -82,6 +82,7 @@
DBusMessage *message,
NihDBusObject *object);
static int nih_dbus_message_destroy (NihDBusMessage *msg);
+static void nih_dbus_release_callback (NihMainLoopFunc *func);
/**
@@ -292,6 +293,18 @@
}
/**
+ * nih_dbus_release_callback:
+ * @func: main loop callback function
+ *
+ * Mark a dbus callback in the main loop deleted.
+ **/
+static void
+nih_dbus_release_callback (NihMainLoopFunc *func)
+{
+ func->delete = TRUE;
+}
+
+/**
* nih_dbus_setup:
* @conn: D-Bus connection to setup,
* @disconnect_handler: function to call on disconnection.
@@ -335,7 +348,7 @@
return -1;
if (! dbus_connection_set_data (conn, main_loop_slot, loop,
- (DBusFreeFunction)nih_free)) {
+ (DBusFreeFunction)nih_dbus_release_callback)) {
nih_free (loop);
return -1;
}
diff --git a/nih/main.c b/nih/main.c
index 45ff36f..a010e2f 100644
--- a/nih/main.c
+++ b/nih/main.c
@@ -617,7 +617,11 @@
NIH_LIST_FOREACH_SAFE (nih_main_loop_functions, iter) {
NihMainLoopFunc *func = (NihMainLoopFunc *)iter;
- func->callback (func->data, func);
+ if (! func->delete) {
+ func->callback (func->data, func);
+ } else {
+ nih_free (iter);
+ }
}
}
@@ -702,6 +706,8 @@
func->callback = callback;
func->data = data;
+ func->delete = FALSE;
+
nih_list_add (nih_main_loop_functions, &func->entry);
return func;
diff --git a/nih/main.h b/nih/main.h
index bd5887c..f827ce9 100644
--- a/nih/main.h
+++ b/nih/main.h
@@ -44,6 +44,7 @@
* @entry: list header,
* @callback: function called,
* @data: pointer passed to @callback.
+ * @delete: the function should be freed instead of run.
*
* This structure contains information about a function that should be
* called once in each main loop iteration.
@@ -56,6 +57,8 @@
NihMainLoopCb callback;
void *data;
+
+ int delete;
};
diff --git a/nih/nih_dbus_tool.py b/nih/nih_dbus_tool.py
index 1dbf5b8..e998578 100644
--- a/nih/nih_dbus_tool.py
+++ b/nih/nih_dbus_tool.py
@@ -1828,6 +1828,7 @@
#include <dbus/dbus.h>
#include <errno.h>
+#include <limits.h>
#include <nih/macros.h>
#include <nih/alloc.h>
diff --git a/nih/tests/test_dbus.c b/nih/tests/test_dbus.c
index 6a25954..568944a 100644
--- a/nih/tests/test_dbus.c
+++ b/nih/tests/test_dbus.c
@@ -212,7 +212,10 @@
TEST_TRUE (disconnected);
TEST_EQ_P (last_connection, conn);
- TEST_FREE (loop_func);
+ TEST_NOT_FREE (loop_func);
+ TEST_TRUE (loop_func->delete);
+
+ nih_free (loop_func);
/* Check that by using a GUID we can reuse connections to the same
@@ -296,7 +299,10 @@
TEST_TRUE (disconnected);
TEST_EQ_P (last_connection, conn);
- TEST_FREE (loop_func);
+ TEST_NOT_FREE (loop_func);
+ TEST_TRUE (loop_func->delete);
+
+ nih_free (loop_func);
/* Check that we can create a new connection to a listening dbus
@@ -328,6 +334,14 @@
TEST_TRUE (disconnected);
TEST_EQ_P (last_connection, conn);
+ /* Reap deleted */
+ NIH_LIST_FOREACH_SAFE (nih_main_loop_functions, iter) {
+ NihMainLoopFunc *func = (NihMainLoopFunc *)iter;
+
+ if (func->delete)
+ nih_free (func);
+ }
+
/* Check that if we create a new connection to a non-listening
* address, no object is returned.
@@ -356,7 +370,7 @@
DBusServer *server;
DBusConnection *conn, *last_conn;
NihIoWatch *io_watch;
- NihMainLoopFunc *loop_func;
+ NihMainLoopFunc *loop_func = NULL;
NihError *err;
pid_t pid1, pid2;
int fd, wait_fd, status;
@@ -399,10 +413,18 @@
TEST_EQ_P (loop_func->data, conn);
+ TEST_FREE_TAG (loop_func);
+
dbus_connection_unref (conn);
system_bus:
dbus_shutdown ();
+ if (loop_func) {
+ TEST_NOT_FREE (loop_func);
+ TEST_TRUE (loop_func->delete);
+ nih_free (loop_func);
+ }
+
/* Check that we can create a connection to the D-Bus system bus,
* the returned object should be hooked up to the main loop.
@@ -423,6 +445,16 @@
TEST_EQ (io_watch->fd, fd);
TEST_NE_P (io_watch->data, NULL);
+#if 0
+ /* Reap deleted */
+ NIH_LIST_FOREACH_SAFE (nih_main_loop_functions, iter) {
+ NihMainLoopFunc *fn = (NihMainLoopFunc *)iter;
+
+ if (fn->marked_deleted)
+ nih_free (fn);
+ }
+#endif
+
/* Should be a single main loop function. */
TEST_LIST_NOT_EMPTY (nih_main_loop_functions);
loop_func = (NihMainLoopFunc *)nih_main_loop_functions->next;
@@ -430,9 +462,15 @@
TEST_EQ_P (loop_func->data, conn);
+ TEST_FREE_TAG (loop_func);
+
dbus_connection_unref (conn);
dbus_shutdown ();
+ TEST_NOT_FREE (loop_func);
+ TEST_TRUE (loop_func->delete);
+ nih_free (loop_func);
+
/* Check that we can share connections to a bus. */
TEST_FEATURE ("with shared bus connection");
@@ -451,6 +489,16 @@
TEST_EQ (io_watch->fd, fd);
TEST_NE_P (io_watch->data, NULL);
+#if 0
+ /* Reap deleted */
+ NIH_LIST_FOREACH_SAFE (nih_main_loop_functions, iter) {
+ NihMainLoopFunc *fn = (NihMainLoopFunc *)iter;
+
+ if (fn->marked_deleted)
+ nih_free (fn);
+ }
+#endif
+
/* Should be a single main loop function. */
TEST_LIST_NOT_EMPTY (nih_main_loop_functions);
loop_func = (NihMainLoopFunc *)nih_main_loop_functions->next;
@@ -475,6 +523,7 @@
/* Should be the same main loop function. */
TEST_NOT_FREE (loop_func);
+ TEST_FALSE (loop_func->delete);
TEST_LIST_NOT_EMPTY (nih_main_loop_functions);
TEST_EQ_P (nih_main_loop_functions->next, &loop_func->entry);
TEST_EQ_P (loop_func->entry.next, nih_main_loop_functions);
@@ -484,6 +533,10 @@
dbus_connection_unref (last_conn);
dbus_shutdown ();
+ TEST_NOT_FREE (loop_func);
+ TEST_TRUE (loop_func->delete);
+ nih_free (loop_func);
+
/* Check that if the bus disconnects before registration, NULL
* is returned along with an error. Stock dbus tends to bail out
@@ -596,6 +649,16 @@
TEST_EQ (io_watch->fd, fd);
TEST_NE_P (io_watch->data, NULL);
+#if 0
+ /* Reap deleted */
+ NIH_LIST_FOREACH_SAFE (nih_main_loop_functions, iter) {
+ NihMainLoopFunc *fn = (NihMainLoopFunc *)iter;
+
+ if (fn->marked_deleted)
+ nih_free (fn);
+ }
+#endif
+
/* Should be a single main loop function. */
TEST_LIST_NOT_EMPTY (nih_main_loop_functions);
loop_func = (NihMainLoopFunc *)nih_main_loop_functions->next;
@@ -625,6 +688,7 @@
/* Should be the same main loop function. */
TEST_NOT_FREE (loop_func);
+ TEST_FALSE (loop_func->delete);
TEST_LIST_NOT_EMPTY (nih_main_loop_functions);
TEST_EQ_P (nih_main_loop_functions->next, &loop_func->entry);
TEST_EQ_P (loop_func->entry.next, nih_main_loop_functions);
@@ -632,6 +696,10 @@
dbus_connection_unref (conn);
dbus_shutdown ();
+
+ TEST_NOT_FREE (loop_func);
+ TEST_TRUE (loop_func->delete);
+ nih_free (loop_func);
}