[gnome-disk-utility] Track ssh connection and emit GduPool::disconnected as appropriate
- From: David Zeuthen <davidz src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnome-disk-utility] Track ssh connection and emit GduPool::disconnected as appropriate
- Date: Sat, 12 Dec 2009 00:10:53 +0000 (UTC)
commit 00b907518c1b4f8c1731c2a6a3f08b4d65520b84
Author: David Zeuthen <davidz redhat com>
Date: Fri Dec 11 19:08:43 2009 -0500
Track ssh connection and emit GduPool::disconnected as appropriate
Also act on this signal in Palimpsest. Still need to add a disconnect
button for the user to press.
Signed-off-by: David Zeuthen <davidz redhat com>
src/gdu/gdu-pool.c | 126 +++++++++++++++++++++++++++++++++++++++-----
src/gdu/gdu-pool.h | 2 +
src/gdu/gdu-ssh-bridge.c | 22 +++++---
src/gdu/gdu-ssh-bridge.h | 4 +-
src/palimpsest/gdu-shell.c | 13 +++++
5 files changed, 142 insertions(+), 25 deletions(-)
---
diff --git a/src/gdu/gdu-pool.c b/src/gdu/gdu-pool.c
index e3630de..1090ebe 100644
--- a/src/gdu/gdu-pool.c
+++ b/src/gdu/gdu-pool.c
@@ -55,6 +55,7 @@
*/
enum {
+ DISCONNECTED,
DEVICE_ADDED,
DEVICE_REMOVED,
DEVICE_CHANGED,
@@ -78,10 +79,16 @@ enum {
static GObjectClass *parent_class = NULL;
static guint signals[LAST_SIGNAL] = { 0 };
+static void _gdu_pool_disconnect (GduPool *pool);
+
struct _GduPoolPrivate
{
+ gboolean is_disconnected;
+
gchar *ssh_user_name;
gchar *ssh_address;
+ GPid ssh_pid;
+ guint ssh_child_watch_id;
DBusGConnection *bus;
DBusGProxy *proxy;
@@ -108,29 +115,28 @@ struct _GduPoolPrivate
G_DEFINE_TYPE (GduPool, gdu_pool, G_TYPE_OBJECT);
+static void remove_all_objects_and_dbus_proxies (GduPool *pool);
+
static void
gdu_pool_finalize (GduPool *pool)
{
- if (pool->priv->bus != NULL)
- dbus_g_connection_unref (pool->priv->bus);
- if (pool->priv->proxy != NULL)
- g_object_unref (pool->priv->proxy);
-
- g_free (pool->priv->daemon_version);
+ g_print ("in gdu_pool_finalize()\n");
- g_list_foreach (pool->priv->known_filesystems, (GFunc) g_object_unref, NULL);
- g_list_free (pool->priv->known_filesystems);
+ remove_all_objects_and_dbus_proxies (pool);
g_hash_table_unref (pool->priv->object_path_to_device);
-
g_hash_table_unref (pool->priv->object_path_to_adapter);
-
g_hash_table_unref (pool->priv->object_path_to_expander);
-
g_hash_table_unref (pool->priv->object_path_to_port);
- g_list_foreach (pool->priv->presentables, (GFunc) g_object_unref, NULL);
- g_list_free (pool->priv->presentables);
+ if (pool->priv->ssh_child_watch_id > 0) {
+ g_source_remove (pool->priv->ssh_child_watch_id);
+ pool->priv->ssh_child_watch_id = 0;
+ }
+ if (pool->priv->ssh_pid > 0) {
+ kill (pool->priv->ssh_pid, SIGTERM);
+ pool->priv->ssh_pid = 0;
+ }
if (G_OBJECT_CLASS (parent_class)->finalize)
(* G_OBJECT_CLASS (parent_class)->finalize) (G_OBJECT (pool));
@@ -148,6 +154,25 @@ gdu_pool_class_init (GduPoolClass *klass)
g_type_class_add_private (klass, sizeof (GduPoolPrivate));
/**
+ * GduPool::disconnected
+ * @pool: The #GduPool emitting the signal.
+ *
+ * Emitted when the underlying connection has been disconnected.
+ *
+ * If you hold a reference to @pool, now is a good time to give it up.
+ */
+ signals[DISCONNECTED] =
+ g_signal_new ("disconnected",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GduPoolClass, disconnected),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ /**
* GduPool::device-added
* @pool: The #GduPool emitting the signal.
* @device: The #GduDevice that was added.
@@ -1711,6 +1736,31 @@ _gdu_pool_get_connection (GduPool *pool)
return pool->priv->bus;
}
+static void
+on_ssh_process_terminated (GPid pid,
+ gint status,
+ gpointer user_data)
+{
+ GduPool *pool = GDU_POOL (user_data);
+
+ g_print ("wohoo, ssh process has been terminated\n");
+
+ /* need to take a temp ref since receivers of the ::disconnected signal
+ * may unref the pool
+ */
+ g_object_ref (pool);
+
+ _gdu_pool_disconnect (pool);
+
+ g_spawn_close_pid (pid);
+
+ g_source_remove (pool->priv->ssh_child_watch_id);
+ pool->priv->ssh_child_watch_id = 0;
+ pool->priv->ssh_pid = 0;
+
+ g_object_unref (pool);
+}
+
GduPool *
gdu_pool_new_for_address (const gchar *ssh_user_name,
const gchar *ssh_address,
@@ -1734,12 +1784,21 @@ gdu_pool_new_for_address (const gchar *ssh_user_name,
goto error;
}
} else {
- pool->priv->bus = _gdu_ssh_bridge_connect (pool, ssh_user_name, ssh_address, error);
+ pool->priv->bus = _gdu_ssh_bridge_connect (ssh_user_name,
+ ssh_address,
+ &(pool->priv->ssh_pid),
+ error);
if (pool->priv->bus == NULL) {
goto error;
}
pool->priv->ssh_user_name = g_strdup (ssh_user_name);
pool->priv->ssh_address = g_strdup (ssh_address);
+
+ /* Watch the ssh process */
+ g_print ("pid is %d\n", pool->priv->ssh_pid);
+ pool->priv->ssh_child_watch_id = g_child_watch_add (pool->priv->ssh_pid,
+ on_ssh_process_terminated,
+ pool);
}
dbus_g_object_register_marshaller (
@@ -2719,3 +2778,42 @@ gdu_pool_get_ssh_address (GduPool *pool)
return pool->priv->ssh_address;
}
+static void
+remove_all_objects_and_dbus_proxies (GduPool *pool)
+{
+ g_free (pool->priv->daemon_version);
+ pool->priv->daemon_version = NULL;
+
+ g_list_foreach (pool->priv->known_filesystems, (GFunc) g_object_unref, NULL);
+ g_list_free (pool->priv->known_filesystems);
+ pool->priv->known_filesystems = NULL;
+
+ g_hash_table_remove_all (pool->priv->object_path_to_device);
+ g_hash_table_remove_all (pool->priv->object_path_to_adapter);
+ g_hash_table_remove_all (pool->priv->object_path_to_expander);
+ g_hash_table_remove_all (pool->priv->object_path_to_port);
+
+ g_list_foreach (pool->priv->presentables, (GFunc) g_object_unref, NULL);
+ g_list_free (pool->priv->presentables);
+ pool->priv->presentables = NULL;
+
+ if (pool->priv->proxy != NULL) {
+ g_object_unref (pool->priv->proxy);
+ pool->priv->proxy = NULL;
+ }
+
+ if (pool->priv->bus != NULL) {
+ dbus_g_connection_unref (pool->priv->bus);
+ pool->priv->bus = NULL;
+ }
+}
+
+static void
+_gdu_pool_disconnect (GduPool *pool)
+{
+ g_return_if_fail (!pool->priv->is_disconnected);
+
+ remove_all_objects_and_dbus_proxies (pool);
+ pool->priv->is_disconnected = TRUE;
+ g_signal_emit (pool, signals[DISCONNECTED], 0);
+}
diff --git a/src/gdu/gdu-pool.h b/src/gdu/gdu-pool.h
index 0bb5d38..9605402 100644
--- a/src/gdu/gdu-pool.h
+++ b/src/gdu/gdu-pool.h
@@ -54,6 +54,8 @@ struct _GduPoolClass
GObjectClass parent_class;
/* signals */
+ void (*disconnected) (GduPool *pool);
+
void (*device_added) (GduPool *pool, GduDevice *device);
void (*device_removed) (GduPool *pool, GduDevice *device);
void (*device_changed) (GduPool *pool, GduDevice *device);
diff --git a/src/gdu/gdu-ssh-bridge.c b/src/gdu/gdu-ssh-bridge.c
index b5780a5..09ee4a7 100644
--- a/src/gdu/gdu-ssh-bridge.c
+++ b/src/gdu/gdu-ssh-bridge.c
@@ -25,6 +25,11 @@
#include <stdio.h>
#include <sys/types.h>
#include <signal.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
#include <gio/gunixinputstream.h>
#include <gio/gunixoutputstream.h>
@@ -183,12 +188,6 @@ on_new_connection (DBusServer *server,
;
}
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-
static void
child_setup (gpointer user_data)
{
@@ -222,9 +221,9 @@ fixup_newlines (gchar *s)
DBusGConnection *
-_gdu_ssh_bridge_connect (GduPool *pool,
- const gchar *ssh_user_name,
+_gdu_ssh_bridge_connect (const gchar *ssh_user_name,
const gchar *ssh_address,
+ GPid *out_pid,
GError **error)
{
BridgeData *data;
@@ -356,7 +355,7 @@ _gdu_ssh_bridge_connect (GduPool *pool,
if (!g_spawn_async_with_pipes (NULL,
ssh_argv,
NULL,
- G_SPAWN_SEARCH_PATH,
+ G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
child_setup,
NULL,
&ssh_pid,
@@ -599,6 +598,11 @@ _gdu_ssh_bridge_connect (GduPool *pool,
if (ssh_pid > 0) {
kill (ssh_pid, SIGTERM);
}
+ if (out_pid != NULL)
+ *out_pid = 0;
+ } else {
+ if (out_pid != NULL)
+ *out_pid = ssh_pid;
}
if (data != NULL)
diff --git a/src/gdu/gdu-ssh-bridge.h b/src/gdu/gdu-ssh-bridge.h
index 73758ba..23e4b61 100644
--- a/src/gdu/gdu-ssh-bridge.h
+++ b/src/gdu/gdu-ssh-bridge.h
@@ -29,9 +29,9 @@
#include <dbus/dbus-glib.h>
#include "gdu-types.h"
-DBusGConnection * _gdu_ssh_bridge_connect (GduPool *pool,
- const gchar *ssh_user_name,
+DBusGConnection * _gdu_ssh_bridge_connect (const gchar *ssh_user_name,
const gchar *ssh_address,
+ GPid *out_pid,
GError **error);
#endif /* __GDU_SSH_BRIDGE_H */
diff --git a/src/palimpsest/gdu-shell.c b/src/palimpsest/gdu-shell.c
index 1a5ede3..3d92509 100644
--- a/src/palimpsest/gdu-shell.c
+++ b/src/palimpsest/gdu-shell.c
@@ -1116,6 +1116,18 @@ gdu_shell_raise_error (GduShell *shell,
g_free (error_text);
}
+static void
+pool_disconnected (GduPool *pool,
+ gpointer user_data)
+{
+ GduShell *shell = GDU_SHELL (user_data);
+
+ g_warn_if_fail (g_ptr_array_remove (shell->priv->pools, pool));
+ g_object_unref (pool);
+
+ gdu_pool_tree_model_set_pools (shell->priv->model, shell->priv->pools);
+}
+
static gboolean
add_pool (GduShell *shell,
const gchar *ssh_user_name,
@@ -1133,6 +1145,7 @@ add_pool (GduShell *shell,
g_signal_connect (pool, "presentable-added", (GCallback) presentable_added, shell);
g_signal_connect (pool, "presentable-removed", (GCallback) presentable_removed, shell);
+ g_signal_connect (pool, "disconnected", (GCallback) pool_disconnected, shell);
g_ptr_array_add (shell->priv->pools, pool);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]