From c0c16ba4f3c6dfb188f712b17d803afbe933df51 Mon Sep 17 00:00:00 2001 From: Timo Dritschler Date: Fri, 6 Feb 2015 16:23:00 +0100 Subject: Added missing cleanup for GIOChannel GSources to client main loop --- src/kiro-client.c | 54 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/src/kiro-client.c b/src/kiro-client.c index 3cf6e62..92fd6b1 100644 --- a/src/kiro-client.c +++ b/src/kiro-client.c @@ -56,8 +56,8 @@ struct _KiroClientPrivate { gboolean close_signal; // Flag used to signal event listening to stop for connection tear-down GMainLoop *main_loop; // Main loop of the server for event polling and handling - GIOChannel *conn_ec; // GLib IO Channel encapsulation for the connection manager event channel - GIOChannel *rdma_ec; // GLib IO Channel encapsulation for the communication event channel + guint rdma_ec_id; // ID of the GSource that will be created for the rdma_ec GIOChannel + guint conn_ec_id; // ID of the GSource that will be created for the conn_ec GIOChannel GThread *main_thread; // Main KIRO client thread }; @@ -295,6 +295,28 @@ start_client_main_loop (gpointer data) } +gboolean +stop_client_main_loop (KiroClientPrivate *priv) +{ + if (priv->close_signal) { + // Get the IO Channels and destroy them. + // This will also unref their respective GIOChannels + GSource *tmp = g_main_context_find_source_by_id (NULL, priv->conn_ec_id); + g_source_destroy (tmp); + priv->conn_ec_id = 0; + + tmp = g_main_context_find_source_by_id (NULL, priv->rdma_ec_id); + g_source_destroy (tmp); + priv->rdma_ec_id = 0; + + g_main_loop_quit (priv->main_loop); + g_debug ("Event handling stopped"); + return FALSE; + } + return TRUE; +} + + int kiro_client_connect (KiroClient *self, const char *address, const char *port) { @@ -379,16 +401,17 @@ kiro_client_connect (KiroClient *self, const char *address, const char *port) priv->ec = priv->conn->channel; //For easy access priv->main_loop = g_main_loop_new (NULL, FALSE); - priv->conn_ec = g_io_channel_unix_new (priv->ec->fd); - priv->rdma_ec = g_io_channel_unix_new (priv->conn->recv_cq_channel->fd); - g_io_add_watch (priv->conn_ec, G_IO_IN | G_IO_PRI, process_cm_event, (gpointer)priv); - g_io_add_watch (priv->rdma_ec, G_IO_IN | G_IO_PRI, process_rdma_event, (gpointer)priv); + g_idle_add ((GSourceFunc)stop_client_main_loop, priv); + GIOChannel *conn_ec = g_io_channel_unix_new (priv->ec->fd); + priv->conn_ec_id = g_io_add_watch (conn_ec, G_IO_IN | G_IO_PRI, process_cm_event, (gpointer)priv); + GIOChannel *rdma_ec = g_io_channel_unix_new (priv->conn->recv_cq_channel->fd); + priv->rdma_ec_id = g_io_add_watch (rdma_ec, G_IO_IN | G_IO_PRI, process_rdma_event, (gpointer)priv); priv->main_thread = g_thread_new ("KIRO Client main loop", start_client_main_loop, priv->main_loop); // We gave control to the main_loop (with add_watch) and don't need our ref // any longer - g_io_channel_unref (priv->conn_ec); - g_io_channel_unref (priv->rdma_ec); + g_io_channel_unref (conn_ec); + g_io_channel_unref (rdma_ec); return 0; @@ -601,27 +624,18 @@ kiro_client_disconnect (KiroClient *self) //Shut down event listening priv->close_signal = TRUE; - g_debug ("Event handling stopped"); + while (g_main_loop_is_running (priv->main_loop)) {}; - // Stop the main loop and clear its memory - g_main_loop_quit (priv->main_loop); + // Main loop stopped. Clear its memory g_main_loop_unref (priv->main_loop); priv->main_loop = NULL; // Ask the main thread to join (It probably already has, but we do it // anyways. Just in case!) g_thread_join (priv->main_thread); + g_thread_unref (priv->main_thread); priv->main_thread = NULL; - // We don't need the connection management IO channel container any more. - // Unref and thus free it. - g_io_channel_unref (priv->conn_ec); - priv->conn_ec = NULL; - - // The same goes for the cp channels - g_io_channel_unref (priv->rdma_ec); - priv->rdma_ec = NULL; - priv->close_signal = FALSE; //kiro_destroy_connection does not free RDMA memory. Therefore, we need to -- cgit v1.2.3