[Xfce4-commits] <tumbler:pre-unmount> Cancel all URIs when the GMount they reside in is about to be unmounted.
Jannis Pohlmann
noreply at xfce.org
Thu Oct 15 16:26:02 CEST 2009
Updating branch refs/heads/pre-unmount
to 965b17ae8dc8090e359161b5e6af2df2eb2cf062 (commit)
from 07b85dd85a3039a52ddf23683ba9a5c32bfb7118 (commit)
commit 965b17ae8dc8090e359161b5e6af2df2eb2cf062
Author: Jannis Pohlmann <jannis at 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)
More information about the Xfce4-commits
mailing list