Updating branch refs/heads/pre-unmount to 965b17ae8dc8090e359161b5e6af2df2eb2cf062 (commit) from 07b85dd85a3039a52ddf23683ba9a5c32bfb7118 (commit)
commit 965b17ae8dc8090e359161b5e6af2df2eb2cf062 Author: Jannis Pohlmann <jan...@xfce.org> Date: Thu Oct 15 16:22:42 2009 +0200 Cancel all URIs when the GMount they reside in is about to be unmounted. This is done so that people don't have to wait so long until they can take out their removable media while the thumbnailer is busy on the device. tumblerd/tumbler-group-scheduler.c | 54 ++++++++++++++++++++++++++++++++++ tumblerd/tumbler-lifo-scheduler.c | 57 ++++++++++++++++++++++++++++++++++- tumblerd/tumbler-scheduler.c | 13 ++++++++ tumblerd/tumbler-scheduler.h | 12 +++++-- tumblerd/tumbler-service.c | 44 +++++++++++++++++++++++++++ 5 files changed, 174 insertions(+), 6 deletions(-) diff --git a/tumblerd/tumbler-group-scheduler.c b/tumblerd/tumbler-group-scheduler.c index 7c4cdf0..d7b6b68 100644 --- a/tumblerd/tumbler-group-scheduler.c +++ b/tumblerd/tumbler-group-scheduler.c @@ -64,6 +64,8 @@ static void tumbler_group_scheduler_push (TumblerScheduler TumblerSchedulerRequest *request); static void tumbler_group_scheduler_unqueue (TumblerScheduler *scheduler, guint handle); +static void tumbler_group_scheduler_cancel_by_mount (TumblerScheduler *scheduler, + GMount *mount); static void tumbler_group_scheduler_finish_request (TumblerGroupScheduler *scheduler, TumblerSchedulerRequest *request); static void tumbler_group_scheduler_unqueue_request (TumblerSchedulerRequest *request, @@ -141,6 +143,7 @@ tumbler_group_scheduler_iface_init (TumblerSchedulerIface *iface) { iface->push = tumbler_group_scheduler_push; iface->unqueue = tumbler_group_scheduler_unqueue; + iface->cancel_by_mount = tumbler_group_scheduler_cancel_by_mount; } @@ -282,6 +285,53 @@ tumbler_group_scheduler_unqueue (TumblerScheduler *scheduler, static void +tumbler_group_scheduler_cancel_by_mount (TumblerScheduler *scheduler, + GMount *mount) +{ + TumblerSchedulerRequest *request; + TumblerGroupScheduler *group_scheduler = TUMBLER_GROUP_SCHEDULER (scheduler); + GFile *mount_point; + GFile *file; + GList *iter; + guint n; + + g_return_if_fail (TUMBLER_IS_GROUP_SCHEDULER (scheduler)); + g_return_if_fail (G_IS_MOUNT (mount)); + + /* determine the root mount point */ + mount_point = g_mount_get_root (mount); + + g_mutex_lock (group_scheduler->mutex); + + /* iterate over all requests */ + for (iter = group_scheduler->requests; iter != NULL; iter = iter->next) + { + request = iter->data; + + /* iterate over all request URIs */ + for (n = 0; request->uris != NULL && request->uris[n] != NULL; ++n) + { + /* determine the enclosing mount for the file */ + file = g_file_new_for_uri (request->uris[n]); + + /* cancel the URI if it lies of the mount point */ + if (g_file_has_prefix (file, mount_point)) + g_cancellable_cancel (request->cancellables[n]); + + /* release the file object */ + g_object_unref (file); + } + } + + g_mutex_unlock (group_scheduler->mutex); + + /* release the mount point */ + g_object_unref (mount_point); +} + + + +static void tumbler_group_scheduler_finish_request (TumblerGroupScheduler *scheduler, TumblerSchedulerRequest *request) { @@ -414,6 +464,10 @@ tumbler_group_scheduler_thread (gpointer data, } g_mutex_unlock (scheduler->mutex); + /* ignore the the URI if has been cancelled already */ + if (g_cancellable_is_cancelled (request->cancellables[n])) + continue; + /* create a file infor for the current URI */ info = tumbler_file_info_new (request->uris[n]); uri_needs_update = FALSE; diff --git a/tumblerd/tumbler-lifo-scheduler.c b/tumblerd/tumbler-lifo-scheduler.c index 2c25517..2501f92 100644 --- a/tumblerd/tumbler-lifo-scheduler.c +++ b/tumblerd/tumbler-lifo-scheduler.c @@ -57,6 +57,8 @@ static void tumbler_lifo_scheduler_push (TumblerScheduler TumblerSchedulerRequest *request); static void tumbler_lifo_scheduler_unqueue (TumblerScheduler *scheduler, guint handle); +static void tumbler_lifo_scheduler_cancel_by_mount (TumblerScheduler *scheduler, + GMount *mount); static void tumbler_lifo_scheduler_finish_request (TumblerLifoScheduler *scheduler, TumblerSchedulerRequest *request); static void tumbler_lifo_scheduler_unqueue_request (TumblerSchedulerRequest *request, @@ -123,6 +125,7 @@ tumbler_lifo_scheduler_iface_init (TumblerSchedulerIface *iface) { iface->push = tumbler_lifo_scheduler_push; iface->unqueue = tumbler_lifo_scheduler_unqueue; + iface->cancel_by_mount = tumbler_lifo_scheduler_cancel_by_mount; } @@ -239,8 +242,7 @@ static void tumbler_lifo_scheduler_unqueue (TumblerScheduler *scheduler, guint handle) { - TumblerLifoScheduler *lifo_scheduler = - TUMBLER_LIFO_SCHEDULER (scheduler); + TumblerLifoScheduler *lifo_scheduler = TUMBLER_LIFO_SCHEDULER (scheduler); g_return_if_fail (TUMBLER_IS_LIFO_SCHEDULER (scheduler)); g_return_if_fail (handle != 0); @@ -258,6 +260,53 @@ tumbler_lifo_scheduler_unqueue (TumblerScheduler *scheduler, static void +tumbler_lifo_scheduler_cancel_by_mount (TumblerScheduler *scheduler, + GMount *mount) +{ + TumblerSchedulerRequest *request; + TumblerLifoScheduler *lifo_scheduler = TUMBLER_LIFO_SCHEDULER (scheduler); + GFile *mount_point; + GFile *file; + GList *iter; + guint n; + + g_return_if_fail (TUMBLER_IS_LIFO_SCHEDULER (scheduler)); + g_return_if_fail (G_IS_MOUNT (mount)); + + /* determine the root mount point */ + mount_point = g_mount_get_root (mount); + + g_mutex_lock (lifo_scheduler->mutex); + + /* iterate over all requests */ + for (iter = lifo_scheduler->requests; iter != NULL; iter = iter->next) + { + request = iter->data; + + /* iterate over all request URIs */ + for (n = 0; request->uris != NULL && request->uris[n] != NULL; ++n) + { + /* determine the enclosing mount for the file */ + file = g_file_new_for_uri (request->uris[n]); + + /* cancel the URI if it lies of the mount point */ + if (g_file_has_prefix (file, mount_point)) + g_cancellable_cancel (request->cancellables[n]); + + /* release the file object */ + g_object_unref (file); + } + } + + g_mutex_unlock (lifo_scheduler->mutex); + + /* release the mount point */ + g_object_unref (mount_point); +} + + + +static void tumbler_lifo_scheduler_finish_request (TumblerLifoScheduler *scheduler, TumblerSchedulerRequest *request) { @@ -348,6 +397,10 @@ tumbler_lifo_scheduler_thread (gpointer data, } g_mutex_unlock (scheduler->mutex); + /* ignore the the URI if has been cancelled already */ + if (g_cancellable_is_cancelled (request->cancellables[n])) + continue; + /* create a file info for the current URI */ info = tumbler_file_info_new (request->uris[n]); uri_needs_update = FALSE; diff --git a/tumblerd/tumbler-scheduler.c b/tumblerd/tumbler-scheduler.c index 055619c..60aad77 100644 --- a/tumblerd/tumbler-scheduler.c +++ b/tumblerd/tumbler-scheduler.c @@ -200,6 +200,19 @@ tumbler_scheduler_unqueue (TumblerScheduler *scheduler, void +tumbler_scheduler_cancel_by_mount (TumblerScheduler *scheduler, + GMount *mount) +{ + g_return_if_fail (TUMBLER_IS_SCHEDULER (scheduler)); + g_return_if_fail (G_IS_MOUNT (mount)); + g_return_if_fail (TUMBLER_SCHEDULER_GET_IFACE (scheduler)->cancel_by_mount != NULL); + + TUMBLER_SCHEDULER_GET_IFACE (scheduler)->cancel_by_mount (scheduler, mount); +} + + + +void tumbler_scheduler_take_request (TumblerScheduler *scheduler, TumblerSchedulerRequest *request) { diff --git a/tumblerd/tumbler-scheduler.h b/tumblerd/tumbler-scheduler.h index 3eaacac..d92a0c7 100644 --- a/tumblerd/tumbler-scheduler.h +++ b/tumblerd/tumbler-scheduler.h @@ -54,10 +54,12 @@ struct _TumblerSchedulerIface guint handle); /* virtual methods */ - void (*push) (TumblerScheduler *scheduler, - TumblerSchedulerRequest *request); - void (*unqueue) (TumblerScheduler *scheduler, - guint handle); + void (*push) (TumblerScheduler *scheduler, + TumblerSchedulerRequest *request); + void (*unqueue) (TumblerScheduler *scheduler, + guint handle); + void (*cancel_by_mount) (TumblerScheduler *scheduler, + GMount *mount); }; GType tumbler_scheduler_get_type (void) G_GNUC_CONST; @@ -66,6 +68,8 @@ void tumbler_scheduler_push (TumblerSchedul TumblerSchedulerRequest *request); void tumbler_scheduler_unqueue (TumblerScheduler *scheduler, guint handle); +void tumbler_scheduler_cancel_by_mount (TumblerScheduler *scheduler, + GMount *mount); gchar* tumbler_scheduler_get_name (TumblerScheduler *scheduler); void tumbler_scheduler_take_request (TumblerScheduler *scheduler, TumblerSchedulerRequest *request); diff --git a/tumblerd/tumbler-service.c b/tumblerd/tumbler-service.c index 3280798..6f9a05a 100644 --- a/tumblerd/tumbler-service.c +++ b/tumblerd/tumbler-service.c @@ -26,6 +26,8 @@ #include <glib/gi18n.h> #include <glib-object.h> +#include <gio/gio.h> + #include <dbus/dbus.h> #include <dbus/dbus-glib.h> #include <dbus/dbus-glib-lowlevel.h> @@ -39,10 +41,14 @@ #include <tumblerd/tumbler-group-scheduler.h> #include <tumblerd/tumbler-utils.h> + + #define THUMBNAILER_PATH "/org/freedesktop/thumbnails/Thumbnailer1" #define THUMBNAILER_SERVICE "org.freedesktop.thumbnails.Thumbnailer1" #define THUMBNAILER_IFACE "org.freedesktop.thumbnails.Thumbnailer1" + + /* signal identifiers */ enum { @@ -92,6 +98,9 @@ static void tumbler_service_scheduler_started (TumblerScheduler *scheduler, guint handle, const gchar *origin, TumblerService *service); +static void tumbler_service_pre_unmount (TumblerService *service, + GMount *mount, + GVolumeMonitor *monitor); @@ -108,6 +117,8 @@ struct _TumblerService TumblerRegistry *registry; GMutex *mutex; GList *schedulers; + + GVolumeMonitor *volume_monitor; }; @@ -205,6 +216,10 @@ tumbler_service_init (TumblerService *service) { service->mutex = g_mutex_new (); service->schedulers = NULL; + + service->volume_monitor = g_volume_monitor_get (); + g_signal_connect_swapped (service->volume_monitor, "mount-pre-unmount", + G_CALLBACK (tumbler_service_pre_unmount), service); } @@ -257,6 +272,13 @@ tumbler_service_finalize (GObject *object) { TumblerService *service = TUMBLER_SERVICE (object); + /* disconnect from the volume monitor */ + g_signal_handlers_disconnect_matched (service->volume_monitor, G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, service); + + /* release the volume monitor */ + g_object_unref (service->volume_monitor); + /* release all schedulers and the scheduler list */ g_list_foreach (service->schedulers, (GFunc) g_object_unref, NULL); g_list_free (service->schedulers); @@ -473,6 +495,27 @@ tumbler_service_scheduler_started (TumblerScheduler *scheduler, +static void +tumbler_service_pre_unmount (TumblerService *service, + GMount *mount, + GVolumeMonitor *volume_monitor) +{ + GList *iter; + + g_return_if_fail (TUMBLER_IS_SERVICE (service)); + g_return_if_fail (G_IS_MOUNT (mount)); + g_return_if_fail (volume_monitor == service->volume_monitor); + + g_mutex_lock (service->mutex); + + for (iter = service->schedulers; iter != NULL; ++iter) + tumbler_scheduler_cancel_by_mount (iter->data, mount); + + g_mutex_unlock (service->mutex); +} + + + TumblerService * tumbler_service_new (DBusGConnection *connection, TumblerRegistry *registry) @@ -673,6 +716,7 @@ tumbler_service_get_supported (TumblerService *service, } + void tumbler_service_get_schedulers (TumblerService *service, DBusGMethodInvocation *context) _______________________________________________ Xfce4-commits mailing list Xfce4-commits@xfce.org http://foo-projects.org/mailman/listinfo/xfce4-commits