[gvfs/wip/udisks2] Use a timeout of ten seconds when spawning commands



commit b6f13596478ddf234ae814cd007ab806a80cb5c1
Author: David Zeuthen <davidz redhat com>
Date:   Thu Dec 22 14:42:54 2011 -0500

    Use a timeout of ten seconds when spawning commands
    
    This is helpful in the presence of e.g. unreachable NFS servers etc.
    
    Signed-off-by: David Zeuthen <davidz redhat com>

 monitor/udisks2/gvfsudisks2mount.c  |    6 +++-
 monitor/udisks2/gvfsudisks2utils.c  |   48 ++++++++++++++++++++++++++++++++++-
 monitor/udisks2/gvfsudisks2utils.h  |    3 +-
 monitor/udisks2/gvfsudisks2volume.c |    3 +-
 4 files changed, 55 insertions(+), 5 deletions(-)
---
diff --git a/monitor/udisks2/gvfsudisks2mount.c b/monitor/udisks2/gvfsudisks2mount.c
index ca1a075..418bd8c 100644
--- a/monitor/udisks2/gvfsudisks2mount.c
+++ b/monitor/udisks2/gvfsudisks2mount.c
@@ -736,7 +736,8 @@ unmount_show_busy (UnmountData  *data,
 {
   gchar *escaped_mount_point;
   escaped_mount_point = g_strescape (mount_point, NULL);
-  gvfs_udisks2_utils_spawn (data->cancellable,
+  gvfs_udisks2_utils_spawn (10, /* timeout in seconds */
+                            data->cancellable,
                             lsof_command_cb,
                             unmount_data_ref (data),
                             "lsof -t \"%s\"",
@@ -874,7 +875,8 @@ unmount_do (UnmountData *data,
     {
       gchar *escaped_mount_path;
       escaped_mount_path = g_strescape (data->mount->mount_path, NULL);
-      gvfs_udisks2_utils_spawn (data->cancellable,
+      gvfs_udisks2_utils_spawn (10, /* timeout in seconds */
+                                data->cancellable,
                                 umount_command_cb,
                                 data,
                                 "umount %s \"%s\"",
diff --git a/monitor/udisks2/gvfsudisks2utils.c b/monitor/udisks2/gvfsudisks2utils.c
index 213c2e7..207777a 100644
--- a/monitor/udisks2/gvfsudisks2utils.c
+++ b/monitor/udisks2/gvfsudisks2utils.c
@@ -129,6 +129,9 @@ typedef struct
   GSource *child_stdout_source;
   GSource *child_stderr_source;
 
+  gboolean timed_out;
+  GSource *timeout_source;
+
   GString *child_stdout;
   GString *child_stderr;
 
@@ -145,6 +148,12 @@ child_watch_from_release_cb (GPid     pid,
 static void
 spawn_data_free (SpawnData *data)
 {
+  if (data->timeout_source != NULL)
+    {
+      g_source_destroy (data->timeout_source);
+      data->timeout_source = NULL;
+    }
+
   /* Nuke the child, if necessary */
   if (data->child_watch_source != NULL)
     {
@@ -312,8 +321,26 @@ child_watch_cb (GPid     pid,
   g_object_unref (data->simple);
 }
 
+static gboolean
+timeout_cb (gpointer user_data)
+{
+  SpawnData *data = user_data;
+
+  data->timed_out = TRUE;
+
+  /* ok, timeout is history, make sure we don't free it in spawn_data_free() */
+  data->timeout_source = NULL;
+
+  /* we're done */
+  g_simple_async_result_complete_in_idle (data->simple);
+  g_object_unref (data->simple);
+
+  return FALSE; /* remove source */
+}
+
 void
-gvfs_udisks2_utils_spawn (GCancellable        *cancellable,
+gvfs_udisks2_utils_spawn (guint                timeout_seconds,
+                          GCancellable        *cancellable,
                           GAsyncReadyCallback  callback,
                           gpointer             user_data,
                           const gchar         *command_line_format,
@@ -404,6 +431,15 @@ gvfs_udisks2_utils_spawn (GCancellable        *cancellable,
       goto out;
     }
 
+  if (timeout_seconds > 0)
+    {
+      data->timeout_source = g_timeout_source_new_seconds (timeout_seconds);
+      g_source_set_priority (data->timeout_source, G_PRIORITY_DEFAULT);
+      g_source_set_callback (data->timeout_source, timeout_cb, data, NULL);
+      g_source_attach (data->timeout_source, data->main_context);
+      g_source_unref (data->timeout_source);
+    }
+
   data->child_watch_source = g_child_watch_source_new (data->child_pid);
   g_source_set_callback (data->child_watch_source, (GSourceFunc) child_watch_cb, data, NULL);
   g_source_attach (data->child_watch_source, data->main_context);
@@ -448,6 +484,16 @@ gvfs_udisks2_utils_spawn_finish (GAsyncResult   *res,
 
   data = g_simple_async_result_get_op_res_gpointer (simple);
 
+  if (data->timed_out)
+    {
+      g_set_error (error,
+                   G_IO_ERROR,
+                   G_IO_ERROR_TIMED_OUT,
+                   _("Timed out running command-line `%s'"),
+                   data->command_line);
+      goto out;
+    }
+
   if (out_exit_status != NULL)
     *out_exit_status = data->exit_status;
 
diff --git a/monitor/udisks2/gvfsudisks2utils.h b/monitor/udisks2/gvfsudisks2utils.h
index 7a6abe7..80cf43d 100644
--- a/monitor/udisks2/gvfsudisks2utils.h
+++ b/monitor/udisks2/gvfsudisks2utils.h
@@ -37,7 +37,8 @@ GIcon *gvfs_udisks2_utils_icon_from_fs_type (const gchar *fs_type);
 gchar *gvfs_udisks2_utils_lookup_fstab_options_value (const gchar *fstab_options,
                                                       const gchar *key);
 
-void     gvfs_udisks2_utils_spawn (GCancellable        *cancellable,
+void     gvfs_udisks2_utils_spawn (guint                timeout_seconds,
+                                   GCancellable        *cancellable,
                                    GAsyncReadyCallback  callback,
                                    gpointer             user_data,
                                    const gchar         *command_line_format,
diff --git a/monitor/udisks2/gvfsudisks2volume.c b/monitor/udisks2/gvfsudisks2volume.c
index 8914b02..bc11868 100644
--- a/monitor/udisks2/gvfsudisks2volume.c
+++ b/monitor/udisks2/gvfsudisks2volume.c
@@ -1055,7 +1055,8 @@ gvfs_udisks2_volume_mount (GVolume             *_volume,
     {
       gchar *escaped_mount_path;
       escaped_mount_path = g_strescape (g_unix_mount_point_get_mount_path (data->volume->mount_point), NULL);
-      gvfs_udisks2_utils_spawn (data->cancellable,
+      gvfs_udisks2_utils_spawn (10, /* timeout in seconds */
+                                data->cancellable,
                                 mount_command_cb,
                                 data,
                                 "mount \"%s\"",



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]