[maemo-commits] [maemo-commits] r16213 - in projects/haf/trunk/hildon-thumbnail: . daemon daemon/plugins debian thumbs
From: subversion at stage.maemo.org subversion at stage.maemo.orgDate: Wed Sep 24 17:42:36 EEST 2008
- Previous message: [maemo-commits] r16212 - projects/haf/branches/hildon-thumbnail/daemonize/thumbs
- Next message: [maemo-commits] r16214 - projects/haf/branches/hildon-thumbnail/daemonize/daemon
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Author: marivoll
Date: 2008-09-24 17:42:35 +0300 (Wed, 24 Sep 2008)
New Revision: 16213
Modified:
projects/haf/trunk/hildon-thumbnail/ChangeLog
projects/haf/trunk/hildon-thumbnail/daemon/hildon-thumbnail-daemon.c
projects/haf/trunk/hildon-thumbnail/daemon/manager.c
projects/haf/trunk/hildon-thumbnail/daemon/plugin-runner.c
projects/haf/trunk/hildon-thumbnail/daemon/plugins/exec-plugin.c
projects/haf/trunk/hildon-thumbnail/daemon/plugins/gdkpixbuf-plugin.c
projects/haf/trunk/hildon-thumbnail/daemon/plugins/gstreamer-video-plugin.c
projects/haf/trunk/hildon-thumbnail/daemon/thumbnailer.c
projects/haf/trunk/hildon-thumbnail/debian/changelog
projects/haf/trunk/hildon-thumbnail/thumbs/hildon-thumbnail-factory.c
Log:
Merged daemonize branch.
[ Philip Van Hoof ]
* Completed API in the daemon.
* Monitor plugin directory.
* Avoid D-Bus roundtrip for existing thumbnails when using the
HildonThumbnailFactory API.
* Handle large requests in a separate thread so that small
requests are not starved.
Modified: projects/haf/trunk/hildon-thumbnail/ChangeLog
===================================================================
--- projects/haf/trunk/hildon-thumbnail/ChangeLog 2008-09-24 13:48:05 UTC (rev 16212)
+++ projects/haf/trunk/hildon-thumbnail/ChangeLog 2008-09-24 14:42:35 UTC (rev 16213)
@@ -1,5 +1,44 @@
+2008-09-24 Philip Van Hoof <pvanhoof at gnome.org>
+
+ * thumbs/hildon-thumbnail-factory.c: Performance improvement when a
+ thumbnail already exists (avoiding a dbus call)
+
+2008-09-23 Philip Van Hoof <pvanhoof at gnome.org>
+
+ * daemon/manager.c: Fixed a crash
+
+2008-09-23 Philip Van Hoof <pvanhoof at gnome.org>
+
+ * daemon/thumbnailer.c: Adding a thread for large tasks
+
+2008-09-20 Philip Van Hoof <pvanhoof at gnome.org>
+
+ * thumbs/hildon-thumbnail-factory.c
+ * daemon/plugin-runner.c
+ * daemon/manager.c
+ * daemon/thumbnailer.c: Various comments and leak fixes
+
+2008-09-18 Philip Van Hoof <pvanhoof at gnome.org>
+
+ * daemon/hildon-thumbnail-daemon.c: File monitoring the plugins
+
+ * daemon/hildon-thumbnail-daemon.c
+ * daemon/manager.c: Using the right kinds of file monitors (dir monitors)
+
2008-09-17 Philip Van Hoof <pvanhoof at gnome.org>
+ * daemon/plugins/gdkpixbuf-plugin.c:
+ * daemon/plugins/exec-plugin.c:
+ * daemon/plugins/gstreamer-video-plugin.c: Fixed memory leaks when errors occur
+
+ * daemon/thumbnailer.c: Implemented the move, copy, delete hint handlers
+
+2008-09-17 Marius Vollmer <marius.vollmer at nokia.com>
+
+ Released 3.0.0
+
+2008-09-17 Philip Van Hoof <pvanhoof at gnome.org>
+
* daemon/plugins/exec-plugin.c
* daemon/manager.c: Respecting the override file
Modified: projects/haf/trunk/hildon-thumbnail/daemon/hildon-thumbnail-daemon.c
===================================================================
--- projects/haf/trunk/hildon-thumbnail/daemon/hildon-thumbnail-daemon.c 2008-09-24 13:48:05 UTC (rev 16212)
+++ projects/haf/trunk/hildon-thumbnail/daemon/hildon-thumbnail-daemon.c 2008-09-24 14:42:35 UTC (rev 16213)
@@ -25,12 +25,14 @@
#include <glib.h>
#include <dbus/dbus-glib-bindings.h>
+#include <gio/gio.h>
#include "hildon-thumbnail-plugin.h"
#include "thumbnailer.h"
#include "manager.h"
+static GHashTable *registrations;
static gboolean do_shut_down_next_time = TRUE;
void
@@ -54,11 +56,117 @@
return shut;
}
+
+static GHashTable*
+init_plugins (DBusGConnection *connection, Thumbnailer *thumbnailer)
+{
+ GHashTable *regs;
+ GModule *module;
+ GError *error = NULL;
+ GDir *dir;
+ const gchar *plugin;
+
+ regs = g_hash_table_new_full (g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) NULL);
+
+
+ /* TODO: Monitor this directory for plugin removals and additions */
+
+ dir = g_dir_open (PLUGINS_DIR, 0, &error);
+
+ if (dir) {
+ while ((plugin = g_dir_read_name (dir)) != NULL) {
+ gboolean cropping;
+
+ if (!g_str_has_suffix (plugin, "." G_MODULE_SUFFIX)) {
+ continue;
+ }
+
+ module = hildon_thumbnail_plugin_load (plugin);
+ hildon_thumbnail_plugin_do_init (module, &cropping,
+ (register_func) thumbnailer_register_plugin,
+ thumbnailer,
+ &error);
+ if (error) {
+ g_warning ("Can't load plugin [%s]: %s\n", plugin,
+ error->message);
+ g_error_free (error);
+ } else
+ g_hash_table_replace (regs, g_strdup (plugin),
+ module);
+ }
+ g_dir_close (dir);
+ }
+
+ return regs;
+}
+
+static void
+stop_plugins (GHashTable *regs, Thumbnailer *thumbnailer)
+{
+ GHashTableIter iter;
+ gpointer key, value;
+
+ g_hash_table_iter_init (&iter, regs);
+
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ thumbnailer_unregister_plugin (thumbnailer, value);
+ hildon_thumbnail_plugin_do_stop (value);
+ }
+}
+
+
+static void
+on_plugin_changed (GFileMonitor *monitor, GFile *file, GFile *other_file, GFileMonitorEvent event_type, gpointer user_data)
+{
+ Thumbnailer *thumbnailer = user_data;
+ GModule *module = NULL;
+ gchar *path = g_file_get_path (other_file);
+
+ if (path) {
+ switch (event_type) {
+ case G_FILE_MONITOR_EVENT_DELETED: {
+ GModule *module = g_hash_table_lookup (registrations, path);
+ if (module) {
+ thumbnailer_unregister_plugin (thumbnailer, module);
+ hildon_thumbnail_plugin_do_stop (module);
+ }
+ }
+ case G_FILE_MONITOR_EVENT_CREATED: {
+ GModule *module = hildon_thumbnail_plugin_load (path);
+ gboolean cropping = FALSE;
+
+ if (module) {
+ GError *error = NULL;
+
+ hildon_thumbnail_plugin_do_init (module, &cropping,
+ (register_func) thumbnailer_register_plugin,
+ thumbnailer,
+ &error);
+ if (error) {
+ g_warning ("Can't load plugin [%s]: %s\n", path,
+ error->message);
+ g_error_free (error);
+ } else
+ g_hash_table_replace (registrations, g_strdup (path),
+ module);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ g_free (path);
+}
+
+
int
main (int argc, char **argv)
{
DBusGConnection *connection;
- GModule *module;
GError *error = NULL;
g_type_init ();
@@ -77,12 +185,8 @@
Manager *manager;
Thumbnailer *thumbnailer;
DBusGProxy *manager_proxy;
- gboolean cropping;
- GDir *dir;
- const gchar *plugin;
- GHashTable *registrations;
- GHashTableIter iter;
- gpointer key, value;
+ GFile *file;
+ GFileMonitor *monitor;
manager_do_init (connection, &manager, &error);
thumbnailer_do_init (connection, manager, &thumbnailer, &error);
@@ -92,32 +196,13 @@
MANAGER_PATH,
MANAGER_INTERFACE);
- registrations = g_hash_table_new_full (g_str_hash, g_str_equal,
- (GDestroyNotify) g_free,
- (GDestroyNotify) NULL);
+ registrations = init_plugins (connection, thumbnailer);
- /* TODO: Monitor this directory for plugin removals and additions */
-
- dir = g_dir_open (PLUGINS_DIR, 0, &error);
+ file = g_file_new_for_path (PLUGINS_DIR);
+ monitor = g_file_monitor_directory (file, G_FILE_MONITOR_NONE, NULL, NULL);
+ g_signal_connect (G_OBJECT (monitor), "changed",
+ G_CALLBACK (on_plugin_changed), thumbnailer);
- if (dir) {
- while ((plugin = g_dir_read_name (dir)) != NULL) {
-
- if (!g_str_has_suffix (plugin, "." G_MODULE_SUFFIX)) {
- continue;
- }
-
- module = hildon_thumbnail_plugin_load (plugin);
- hildon_thumbnail_plugin_do_init (module, &cropping,
- (register_func) thumbnailer_register_plugin,
- thumbnailer,
- &error);
- g_hash_table_replace (registrations, g_strdup (plugin),
- module);
- }
- g_dir_close (dir);
- }
-
main_loop = g_main_loop_new (NULL, FALSE);
g_timeout_add_seconds (600,
@@ -126,12 +211,10 @@
g_main_loop_run (main_loop);
- g_hash_table_iter_init (&iter, registrations);
+ g_object_unref (monitor);
+ g_object_unref (file);
- while (g_hash_table_iter_next (&iter, &key, &value)) {
- thumbnailer_unregister_plugin (thumbnailer, value);
- hildon_thumbnail_plugin_do_stop (value);
- }
+ stop_plugins (registrations, thumbnailer);
g_hash_table_unref (registrations);
Modified: projects/haf/trunk/hildon-thumbnail/daemon/manager.c
===================================================================
--- projects/haf/trunk/hildon-thumbnail/daemon/manager.c 2008-09-24 13:48:05 UTC (rev 16212)
+++ projects/haf/trunk/hildon-thumbnail/daemon/manager.c 2008-09-24 14:42:35 UTC (rev 16213)
@@ -32,6 +32,9 @@
#include "dbus-utils.h"
#include "thumbnailer.h"
+static GFile *homedir, *thumbdir;
+static GFileMonitor *homemon, *thumbmon;
+
#define MANAGER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TYPE_MANAGER, ManagerPrivate))
G_DEFINE_TYPE (Manager, manager, G_TYPE_OBJECT)
@@ -325,7 +328,7 @@
gchar *path = g_file_get_path (file);
gboolean override = (strcmp (THUMBNAILERS_DIR, path) == 0);
- /* We override when it's the one in the user's homedir*/
+ /* We override when it's the dir in the user's homedir*/
manager_check_dir (MANAGER (user_data), path, override);
g_free (path);
@@ -341,7 +344,6 @@
{
ManagerPrivate *priv = MANAGER_GET_PRIVATE (object);
GFileMonitor *monitor;
- GFile *file;
gchar *home_thumbnlrs = g_build_filename (g_get_user_data_dir (),
"thumbnailers", NULL);
@@ -353,25 +355,19 @@
manager_check_dir (object, home_thumbnlrs, TRUE);
/* Monitor the dir for changes */
- file = g_file_new_for_path (home_thumbnlrs);
- monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, NULL);
- g_signal_connect (G_OBJECT (monitor), "changed",
+ homedir = g_file_new_for_path (home_thumbnlrs);
+ homemon = g_file_monitor_directory (homedir, G_FILE_MONITOR_NONE, NULL, NULL);
+ g_signal_connect (G_OBJECT (homemon), "changed",
G_CALLBACK (on_dir_changed), NULL);
- // g_object_unref (file)
- // g_object_unref (monitor)
-
/* Monitor the dir for changes */
- file = g_file_new_for_path (THUMBNAILERS_DIR);
- monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, NULL);
- g_signal_connect (G_OBJECT (monitor), "changed",
+ thumbdir = g_file_new_for_path (THUMBNAILERS_DIR);
+ thumbmon = g_file_monitor_directory (thumbdir, G_FILE_MONITOR_NONE, NULL, NULL);
+ g_signal_connect (G_OBJECT (thumbmon), "changed",
G_CALLBACK (on_dir_changed), NULL);
g_mutex_unlock (priv->mutex);
- // g_object_unref (file)
- // g_object_unref (monitor)
-
g_free (home_thumbnlrs);
}
@@ -600,6 +596,10 @@
void
manager_do_stop (void)
{
+ g_object_unref (homemon);
+ g_object_unref (thumbmon);
+ g_object_unref (homedir);
+ g_object_unref (thumbdir);
}
void
Modified: projects/haf/trunk/hildon-thumbnail/daemon/plugin-runner.c
===================================================================
--- projects/haf/trunk/hildon-thumbnail/daemon/plugin-runner.c 2008-09-24 13:48:05 UTC (rev 16212)
+++ projects/haf/trunk/hildon-thumbnail/daemon/plugin-runner.c 2008-09-24 14:42:35 UTC (rev 16213)
@@ -67,11 +67,38 @@
#define plugin_runner_create daemon_create
+
+static gboolean do_shut_down_next_time = TRUE;
+
+static void
+keep_alive (void)
+{
+ do_shut_down_next_time = FALSE;
+}
+
+static gboolean
+shut_down_after_timeout (gpointer user_data)
+{
+ GMainLoop *main_loop = user_data;
+ gboolean shut = FALSE;
+
+ if (do_shut_down_next_time) {
+ g_main_loop_quit (main_loop);
+ shut = TRUE;
+ } else
+ do_shut_down_next_time = TRUE;
+
+ return shut;
+}
+
void
daemon_create (Daemon *object, GStrv uris, DBusGMethodInvocation *context)
{
DaemonPrivate *priv = DAEMON_GET_PRIVATE (object);
GError *error = NULL;
+
+ keep_alive ();
+
hildon_thumbnail_plugin_do_create (priv->module, uris, &error);
if (error) {
dbus_g_method_return_error (context, error);
@@ -230,6 +257,7 @@
static gboolean dynamic_register = FALSE;
static gchar *bus_name;
static gchar *bus_path;
+static gint timeout = 600;
static GOptionEntry entries_daemon[] = {
{ "module-name", 'm', G_OPTION_FLAG_REVERSE|G_OPTION_FLAG_OPTIONAL_ARG,
@@ -240,6 +268,10 @@
G_OPTION_ARG_STRING, &bus_name,
"Busname to use (eg. com.company.Thumbnailer) ",
NULL },
+ { "timeout", 't', 0,
+ G_OPTION_ARG_INT, &timeout,
+ "Timeout before the specialized thumbnailer dies (use -1 for inlimited)",
+ NULL },
{ "bus-path", 'p', 0,
G_OPTION_ARG_STRING, &bus_path,
"Buspath to use (eg. /com/company/Thumbnailer) ",
@@ -316,6 +348,11 @@
daemon_start (DAEMON (object), dynamic_register);
+ if (timeout > -1)
+ g_timeout_add_seconds (timeout,
+ shut_down_after_timeout,
+ main_loop);
+
main_loop = g_main_loop_new (NULL, FALSE);
g_main_loop_run (main_loop);
Modified: projects/haf/trunk/hildon-thumbnail/daemon/plugins/exec-plugin.c
===================================================================
--- projects/haf/trunk/hildon-thumbnail/daemon/plugins/exec-plugin.c 2008-09-24 13:48:05 UTC (rev 16212)
+++ projects/haf/trunk/hildon-thumbnail/daemon/plugins/exec-plugin.c 2008-09-24 14:42:35 UTC (rev 16213)
@@ -293,15 +293,17 @@
g_free (r_exec);
-// TODO
-// if (on_error) {
-// if (!errors)
-// errors = g_string_new ("");
-// g_string_append_printf (errors, "error msg")
-// }
+ nerror_handler:
- nerror_handler:
+ if (nerror) {
+ if (!errors)
+ errors = g_string_new ("");
+ g_string_append_printf (errors, "[`%s': %s] ",
+ uri, nerror->message);
+ g_error_free (nerror);
+ nerror = NULL;
+ }
if (file)
g_object_unref (file);
Modified: projects/haf/trunk/hildon-thumbnail/daemon/plugins/gdkpixbuf-plugin.c
===================================================================
--- projects/haf/trunk/hildon-thumbnail/daemon/plugins/gdkpixbuf-plugin.c 2008-09-24 13:48:05 UTC (rev 16212)
+++ projects/haf/trunk/hildon-thumbnail/daemon/plugins/gdkpixbuf-plugin.c 2008-09-24 14:42:35 UTC (rev 16213)
@@ -333,8 +333,9 @@
if (!errors)
errors = g_string_new ("");
g_string_append_printf (errors, "[`%s': %s] ",
- uri,
- nerror->message);
+ uri, nerror->message);
+ g_error_free (nerror);
+ nerror = NULL;
}
if (stream)
Modified: projects/haf/trunk/hildon-thumbnail/daemon/plugins/gstreamer-video-plugin.c
===================================================================
--- projects/haf/trunk/hildon-thumbnail/daemon/plugins/gstreamer-video-plugin.c 2008-09-24 13:48:05 UTC (rev 16212)
+++ projects/haf/trunk/hildon-thumbnail/daemon/plugins/gstreamer-video-plugin.c 2008-09-24 14:42:35 UTC (rev 16213)
@@ -460,8 +460,9 @@
if (!errors)
errors = g_string_new ("");
g_string_append_printf (errors, "[`%s': %s] ",
- uris[i],
- nerror->message);
+ uris[i], nerror->message);
+ g_error_free (nerror);
+ nerror = NULL;
}
g_free (large);
Modified: projects/haf/trunk/hildon-thumbnail/daemon/thumbnailer.c
===================================================================
--- projects/haf/trunk/hildon-thumbnail/daemon/thumbnailer.c 2008-09-24 13:48:05 UTC (rev 16212)
+++ projects/haf/trunk/hildon-thumbnail/daemon/thumbnailer.c 2008-09-24 14:42:35 UTC (rev 16213)
@@ -39,6 +39,9 @@
#include "dbus-utils.h"
#include "utils.h"
+#define THUMB_ERROR_DOMAIN "HildonThumbnailer"
+#define THUMB_ERROR g_quark_from_static_string (THUMB_ERROR_DOMAIN)
+
#define THUMBNAILER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TYPE_THUMBNAILER, ThumbnailerPrivate))
G_DEFINE_TYPE (Thumbnailer, thumbnailer, G_TYPE_OBJECT)
@@ -49,7 +52,8 @@
typedef struct {
Manager *manager;
GHashTable *plugins;
- GThreadPool *pool;
+ GThreadPool *large_pool;
+ GThreadPool *normal_pool;
GMutex *mutex;
GList *tasks;
} ThumbnailerPrivate;
@@ -74,11 +78,12 @@
{
ThumbnailerPrivate *priv = THUMBNAILER_GET_PRIVATE (object);
+ g_mutex_lock (priv->mutex);
g_hash_table_insert (priv->plugins,
g_strdup (mime_type),
plugin);
manager_i_have (priv->manager, mime_type);
-
+ g_mutex_unlock (priv->mutex);
}
static gboolean
@@ -94,9 +99,11 @@
{
ThumbnailerPrivate *priv = THUMBNAILER_GET_PRIVATE (object);
+ g_mutex_lock (priv->mutex);
g_hash_table_foreach_remove (priv->plugins,
do_delete_or_not,
plugin);
+ g_mutex_unlock (priv->mutex);
}
@@ -140,6 +147,7 @@
Thumbnailer *object;
GStrv urls;
guint num;
+ gboolean poolmax;
gboolean unqueued;
} WorkTask;
@@ -189,11 +197,16 @@
task->num = ++num;
task->object = g_object_ref (object);
task->urls = g_strdupv (urls);
+ task->poolmax = FALSE;
+
g_mutex_lock (priv->mutex);
g_list_foreach (priv->tasks, (GFunc) mark_unqueued, (gpointer) handle_to_unqueue);
priv->tasks = g_list_prepend (priv->tasks, task);
- g_thread_pool_push (priv->pool, task, NULL);
+ if (g_strv_length (urls) > 10)
+ g_thread_pool_push (priv->large_pool, task, NULL);
+ else
+ g_thread_pool_push (priv->normal_pool, task, NULL);
g_mutex_unlock (priv->mutex);
dbus_g_method_return (context, num);
@@ -342,7 +355,12 @@
* plugin have a go at it */
} else {
- GModule *module = g_hash_table_lookup (priv->plugins, key);
+ GModule *module;
+
+ g_mutex_lock (priv->mutex);
+ module = g_hash_table_lookup (priv->plugins, key);
+ g_mutex_unlock (priv->mutex);
+
if (module) {
GError *error = NULL;
@@ -393,39 +411,219 @@
void
thumbnailer_move (Thumbnailer *object, GStrv from_urls, GStrv to_urls, DBusGMethodInvocation *context)
{
+ guint i = 0;
+ GString *errors = NULL;
+ GError *error = NULL;
+
dbus_async_return_if_fail (from_urls != NULL, context);
dbus_async_return_if_fail (to_urls != NULL, context);
keep_alive ();
- // TODO
-
- dbus_g_method_return (context);
+ while (from_urls[i] != NULL && to_urls[i] != NULL) {
+
+ const gchar *from_uri = from_urls[i];
+ const gchar *to_uri = to_urls[i];
+ GError *nerror = NULL;
+ gchar *from_normal = NULL,
+ *from_large = NULL,
+ *from_cropped = NULL;
+ gchar *to_normal = NULL,
+ *to_large = NULL,
+ *to_cropped = NULL;
+
+ hildon_thumbnail_util_get_thumb_paths (from_uri, &from_large,
+ &from_normal,
+ &from_cropped, &error);
+
+ if (nerror)
+ goto nerror_handler;
+
+ hildon_thumbnail_util_get_thumb_paths (from_uri, &to_large,
+ &to_normal,
+ &to_cropped, &error);
+
+ if (nerror)
+ goto nerror_handler;
+
+
+ g_rename (from_large, to_large);
+ g_rename (from_normal, to_normal);
+ g_rename (from_cropped, to_cropped);
+
+ nerror_handler:
+
+ if (nerror) {
+ if (!errors)
+ errors = g_string_new ("");
+ g_string_append_printf (errors, "[`%s': %s] ",
+ from_urls[i],
+ nerror->message);
+ g_error_free (nerror);
+ nerror = NULL;
+ }
+
+ g_free (from_normal);
+ g_free (from_large);
+ g_free (from_cropped);
+ g_free (to_normal);
+ g_free (to_large);
+ g_free (to_cropped);
+
+ i++;
+ }
+
+ if (errors) {
+ g_set_error (&error, THUMB_ERROR, 0,
+ errors->str);
+ g_string_free (errors, TRUE);
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+ } else
+ dbus_g_method_return (context);
}
void
thumbnailer_copy (Thumbnailer *object, GStrv from_urls, GStrv to_urls, DBusGMethodInvocation *context)
{
+ guint i = 0;
+ GString *errors = NULL;
+ GError *error = NULL;
+
dbus_async_return_if_fail (from_urls != NULL, context);
dbus_async_return_if_fail (to_urls != NULL, context);
keep_alive ();
- // TODO
-
- dbus_g_method_return (context);
+ while (from_urls[i] != NULL && to_urls[i] != NULL) {
+
+ const gchar *from_uri = from_urls[i];
+ const gchar *to_uri = to_urls[i];
+ GError *nerror = NULL;
+ gchar *from_s[3] = { NULL, NULL, NULL };
+ gchar *to_s[3] = { NULL, NULL, NULL };
+ guint n;
+
+ hildon_thumbnail_util_get_thumb_paths (from_uri, &from_s[0],
+ &from_s[1],
+ &from_s[2], &error);
+
+ if (nerror)
+ goto nerror_handler;
+
+ hildon_thumbnail_util_get_thumb_paths (from_uri, &to_s[0],
+ &to_s[1],
+ &to_s[2], &error);
+
+ for (n = 0; n<3; n++) {
+ GFile *from, *to;
+
+ if (!from_s[n] || !to_s[n])
+ continue;
+
+ from = g_file_new_for_path (from_s[n]);
+ to = g_file_new_for_path (to_s[n]);
+
+ /* We indeed ignore copy errors here */
+
+ g_file_copy (from, to,
+ G_FILE_COPY_NONE|G_FILE_COPY_OVERWRITE|G_FILE_COPY_ALL_METADATA,
+ NULL, NULL, NULL,
+ NULL);
+
+ g_object_unref (from);
+ g_object_unref (to);
+
+ }
+
+ nerror_handler:
+
+ if (nerror) {
+ if (!errors)
+ errors = g_string_new ("");
+ g_string_append_printf (errors, "[`%s': %s] ",
+ from_urls[i],
+ nerror->message);
+ g_error_free (nerror);
+ nerror = NULL;
+ }
+
+ for (n = 0; n<3; n++) {
+ /* These can be NULL, but that's ok for g_free */
+ g_free (from_s[n]);
+ g_free (to_s[n]);
+ }
+
+ i++;
+ }
+
+ if (errors) {
+ g_set_error (&error, THUMB_ERROR, 0,
+ errors->str);
+ g_string_free (errors, TRUE);
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+ } else
+ dbus_g_method_return (context);
}
void
thumbnailer_delete (Thumbnailer *object, GStrv urls, DBusGMethodInvocation *context)
{
+ guint i = 0;
+ GString *errors = NULL;
+ GError *error = NULL;
+
dbus_async_return_if_fail (urls != NULL, context);
keep_alive ();
- // TODO
-
- dbus_g_method_return (context);
+ while (urls[i] != NULL) {
+
+ const gchar *uri = urls[i];
+ GError *nerror = NULL;
+ gchar *normal = NULL,
+ *large = NULL,
+ *cropped = NULL;
+
+ hildon_thumbnail_util_get_thumb_paths (uri, &large,
+ &normal,
+ &cropped, &error);
+
+ if (nerror)
+ goto nerror_handler;
+
+ g_unlink (large);
+ g_unlink (normal);
+ g_unlink (cropped);
+
+ nerror_handler:
+
+ if (nerror) {
+ if (!errors)
+ errors = g_string_new ("");
+ g_string_append_printf (errors, "[`%s': %s] ",
+ urls[i],
+ nerror->message);
+ g_error_free (nerror);
+ nerror = NULL;
+ }
+
+ g_free (normal);
+ g_free (large);
+ g_free (cropped);
+
+ i++;
+ }
+
+ if (errors) {
+ g_set_error (&error, THUMB_ERROR, 0,
+ errors->str);
+ g_string_free (errors, TRUE);
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+ } else
+ dbus_g_method_return (context);
}
static void
@@ -433,7 +631,8 @@
{
ThumbnailerPrivate *priv = THUMBNAILER_GET_PRIVATE (object);
- g_thread_pool_free (priv->pool, TRUE, TRUE);
+ g_thread_pool_free (priv->normal_pool, TRUE, TRUE);
+ g_thread_pool_free (priv->large_pool, TRUE, TRUE);
g_object_unref (priv->manager);
g_hash_table_unref (priv->plugins);
@@ -567,11 +766,14 @@
/* We could increase the amount of threads to add some parallelism */
- priv->pool = g_thread_pool_new ((GFunc) do_the_work,NULL,1,TRUE,NULL);
+ priv->large_pool = g_thread_pool_new ((GFunc) do_the_work,NULL,1,TRUE,NULL);
+ priv->normal_pool = g_thread_pool_new ((GFunc) do_the_work,NULL,1,TRUE,NULL);
/* This sort function makes the pool a LIFO */
- g_thread_pool_set_sort_function (priv->pool, pool_sort_compare, NULL);
+ g_thread_pool_set_sort_function (priv->large_pool, pool_sort_compare, NULL);
+ g_thread_pool_set_sort_function (priv->normal_pool, pool_sort_compare, NULL);
+
}
Modified: projects/haf/trunk/hildon-thumbnail/debian/changelog
===================================================================
--- projects/haf/trunk/hildon-thumbnail/debian/changelog 2008-09-24 13:48:05 UTC (rev 16212)
+++ projects/haf/trunk/hildon-thumbnail/debian/changelog 2008-09-24 14:42:35 UTC (rev 16213)
@@ -1,3 +1,15 @@
+hildon-thumbnail (3.0.1~unreleased) unstable; urgency=low
+
+ [ Philip Van Hoof ]
+ * Completed API in the daemon.
+ * Monitor plugin directory.
+ * Avoid D-Bus roundtrip for existing thumbnails when using the
+ HildonThumbnailFactory API.
+ * Handle large requests in a separate thread so that small
+ requests are not starved.
+
+ -- Marius Vollmer <marius.vollmer at nokia.com> Wed, 24 Sep 2008 17:35:38 +0300
+
hildon-thumbnail (3.0.0) unstable; urgency=low
[ Philip Van Hoof ]
Modified: projects/haf/trunk/hildon-thumbnail/thumbs/hildon-thumbnail-factory.c
===================================================================
--- projects/haf/trunk/hildon-thumbnail/thumbs/hildon-thumbnail-factory.c 2008-09-24 13:48:05 UTC (rev 16212)
+++ projects/haf/trunk/hildon-thumbnail/thumbs/hildon-thumbnail-factory.c 2008-09-24 14:42:35 UTC (rev 16213)
@@ -101,26 +101,16 @@
}
static void
-on_task_finished (DBusGProxy *proxy,
- guint handle,
- gpointer user_data)
+create_pixbuf_and_callback (ThumbsItem *item, gchar *large, gchar *normal, gchar *cropped)
{
- gchar *key = g_strdup_printf ("%d", handle);
- ThumbsItem *item = g_hash_table_lookup (tasks, key);
-
- if (item) {
+ GFile *filei = NULL;
+ GInputStream *stream = NULL;
GdkPixbuf *pixbuf = NULL;
- gchar *large = NULL, *normal = NULL, *cropped = NULL;
+ gchar *path;
GError *error = NULL;
- gchar *path = NULL;
- GFile *filei = NULL;
- GInputStream *stream = NULL;
- hildon_thumbnail_util_get_thumb_paths (item->uri, &large, &normal, &cropped, &error);
+ /* Determine the exact type of thumbnail being requested */
- if (error)
- goto error_handler;
-
if (item->flags & HILDON_THUMBNAIL_FLAG_CROP) {
path = g_strdup (cropped);
} else if (item->width > 128) {
@@ -129,20 +119,26 @@
path = g_strdup (normal);
}
+ /* Open the original thumbnail as a stream */
filei = g_file_new_for_path (path);
stream = G_INPUT_STREAM (g_file_read (filei, NULL, &error));
+ g_free (path);
if (error)
goto error_handler;
+ /* Read the stream as a pixbuf at the requested exact scale */
pixbuf = gdk_pixbuf_new_from_stream_at_scale (stream,
item->width, item->height, TRUE,
NULL, &error);
error_handler:
+ /* Callback user function, passing the pixbuf and error */
+
item->callback (item, item->user_data, pixbuf, error);
+ /* Cleanup */
if (filei)
g_object_unref (filei);
@@ -156,11 +152,40 @@
if (pixbuf)
gdk_pixbuf_unref (pixbuf);
+}
+static void
+on_task_finished (DBusGProxy *proxy,
+ guint handle,
+ gpointer user_data)
+{
+ gchar *key = g_strdup_printf ("%d", handle);
+ ThumbsItem *item = g_hash_table_lookup (tasks, key);
+
+ if (item) {
+ gchar *large = NULL, *normal = NULL, *cropped = NULL;
+ GError *error = NULL;
+
+ /* Get the large small and cropped path for the original
+ * URI */
+
+ hildon_thumbnail_util_get_thumb_paths (item->uri, &large,
+ &normal, &cropped,
+ &error);
+
+ if (error)
+ goto error_handler;
+
+ create_pixbuf_and_callback (item, large, normal, cropped);
+
+ error_handler:
+
g_free (cropped);
g_free (normal);
g_free (large);
+ /* Remove the key from the hash, which means that we declare it
+ * handled. */
g_hash_table_remove (tasks, key);
}
@@ -185,10 +210,10 @@
GError *error = NULL;
guint64 mtime, size;
- file_path = g_build_filename(path, file, NULL);
+ file_path = g_build_filename (path, file, NULL);
if(file[0] == '.' || !g_file_test(file_path, G_FILE_TEST_IS_REGULAR)) {
- g_free(file_path);
+ g_free (file_path);
continue;
}
@@ -202,6 +227,7 @@
if (error) {
g_error_free (error);
g_object_unref (filei);
+ g_free (file_path);
continue;
}
@@ -226,15 +252,15 @@
static void
cache_file_free(ThumbsCacheFile *item)
{
- g_free(item->file);
- g_free(item);
+ g_free (item->file);
+ g_free (item);
}
static gint
cache_file_compare(gconstpointer a, gconstpointer b)
{
ThumbsCacheFile *f1 = *(ThumbsCacheFile**)a,
- *f2 = *(ThumbsCacheFile**)b;
+ *f2 = *(ThumbsCacheFile**)b;
/* Sort in descending order */
if(f2->mtime == f1->mtime) {
@@ -251,10 +277,8 @@
void
hildon_thumbnail_factory_clean_cache(gint max_size, time_t min_mtime)
{
-
GPtrArray *files;
int i, size = 0;
- gboolean deleting = FALSE;
gchar *large_dir = g_build_filename (g_get_home_dir (), ".thumbnails", "large", NULL);
gchar *normal_dir = g_build_filename (g_get_home_dir (), ".thumbnails", "normal", NULL);
gchar *cropped_dir = g_build_filename (g_get_home_dir (), ".thumbnails", "cropped", NULL);
@@ -264,30 +288,25 @@
files = g_ptr_array_new();
- read_cache_dir(fail_dir, files);
- read_cache_dir(large_dir, files);
- read_cache_dir(normal_dir, files);
- read_cache_dir(cropped_dir, files);
+ read_cache_dir (fail_dir, files);
+ read_cache_dir (large_dir, files);
+ read_cache_dir (normal_dir, files);
+ read_cache_dir (cropped_dir, files);
- g_ptr_array_sort(files, cache_file_compare);
+ g_ptr_array_sort (files, cache_file_compare);
for(i = 0; i < files->len; i++) {
- ThumbsCacheFile *item = g_ptr_array_index(files, i);
+ ThumbsCacheFile *item = g_ptr_array_index (files, i);
size += item->size;
-
- if((max_size >= 0 && size >= max_size) || item->mtime < min_mtime) {
- deleting = TRUE;
+ if ((max_size >= 0 && size >= max_size) || item->mtime < min_mtime) {
+ unlink (item->file);
}
-
- if(deleting) {
- unlink(item->file);
- }
}
- g_ptr_array_foreach(files, (GFunc)cache_file_free, NULL);
+ g_ptr_array_foreach (files, (GFunc)cache_file_free, NULL);
+ g_ptr_array_free (files, TRUE);
- g_ptr_array_free(files, TRUE);
g_free (fail_dir);
g_free (normal_dir);
g_free (large_dir);
@@ -300,9 +319,37 @@
ThumbsItem *item = userdata;
gchar *key = g_strdup_printf ("%d", OUT_handle);
item->handle_id = OUT_handle;
+
+ /* Register the item as being handled */
g_hash_table_replace (tasks, key, item);
}
+typedef struct {
+ gchar *large, *normal, *cropped;
+ ThumbsItem *item;
+} ThumbsItemAndPaths;
+
+static void
+free_thumbsitem_and_paths (ThumbsItemAndPaths *info)
+{
+ g_free (info->large);
+ g_free (info->normal);
+ g_free (info->cropped);
+ thumb_item_free (info->item);
+ g_slice_free (ThumbsItemAndPaths, info);
+}
+
+static gboolean
+have_all_cb (gpointer user_data)
+{
+ ThumbsItemAndPaths *info = user_data;
+ ThumbsItem *item = info->item;
+
+ create_pixbuf_and_callback (item, info->large, info->normal, info->cropped);
+
+ return FALSE;
+}
+
HildonThumbnailFactoryHandle hildon_thumbnail_factory_load_custom(
const gchar *uri, const gchar *mime_type,
guint width, guint height,
@@ -310,35 +357,43 @@
gpointer user_data,
HildonThumbnailFlags flags, ...)
{
+ gchar *large, *normal, *cropped;
+ GError *error = NULL;
ThumbsItem *item;
- GStrv uris = (GStrv) g_malloc0 (sizeof (gchar *) * 2);
+ GStrv uris;
+ gboolean have_all = FALSE;
g_return_val_if_fail(uri != NULL && mime_type != NULL && callback != NULL,
NULL);
- init ();
+ hildon_thumbnail_util_get_thumb_paths (uri, &large, &normal,
+ &cropped, &error);
if (flags & HILDON_THUMBNAIL_FLAG_RECREATE) {
- gchar *large, *normal, *cropped;
- GError *error = NULL;
-
- hildon_thumbnail_util_get_thumb_paths (uri, &large, &normal,
- &cropped, &error);
-
if (!error) {
g_unlink (large);
g_unlink (normal);
g_unlink (cropped);
- } else
- g_error_free (error);
-
- g_free (large);
- g_free (normal);
- g_free (cropped);
+ }
+ } else {
+ gchar *path;
+ if (item->flags & HILDON_THUMBNAIL_FLAG_CROP) {
+ path = cropped;
+ } else if (item->width > 128) {
+ path = large;
+ } else {
+ path = normal;
+ }
+ have_all = g_file_test (path, G_FILE_TEST_EXISTS);
}
- item = g_new(ThumbsItem, 1);
+ if (error)
+ g_error_free (error);
+ else
+ have_all = FALSE;
+ item = g_new (ThumbsItem, 1);
+
item->uri = g_strdup(uri);
item->mime_type = g_strdup(mime_type);
item->width = width;
@@ -349,13 +404,35 @@
item->canceled = FALSE;
item->handle_id = 0;
- uris[0] = g_strdup (uri);
+ if (have_all) {
+ ThumbsItemAndPaths *info = g_slice_new (ThumbsItemAndPaths);
- org_freedesktop_thumbnailer_Generic_queue_async (proxy, (const char **) uris, 0,
- on_got_handle, item);
+ info->item = item;
+ info->normal = g_strdup (normal);
+ info->large = g_strdup (large);
+ info->cropped = g_strdup (cropped);
- g_strfreev (uris);
+ g_idle_add_full (G_PRIORITY_DEFAULT, have_all_cb, info,
+ (GDestroyNotify) free_thumbsitem_and_paths);
+ return;
+ }
+
+ g_free (large);
+ g_free (normal);
+ g_free (cropped);
+
+ if (!have_all) {
+
+ init ();
+ uris = (GStrv) g_malloc0 (sizeof (gchar *) * 2);
+ uris[0] = g_strdup (uri);
+ org_freedesktop_thumbnailer_Generic_queue_async (proxy, (const char **) uris, 0,
+ on_got_handle, item);
+
+ g_strfreev (uris);
+ }
+
return THUMBS_HANDLE (item);
}
@@ -374,6 +451,8 @@
{
ThumbsItem *item = userdata;
gchar *key = g_strdup_printf ("%d", item->handle_id);
+
+ /* Unregister the item */
g_hash_table_remove (tasks, key);
g_free (key);
}
@@ -387,6 +466,7 @@
if (item->handle_id == 0)
return;
+ /* We don't do real canceling, we just do unqueing */
org_freedesktop_thumbnailer_Generic_unqueue_async (proxy, item->handle_id,
on_cancelled, item);
- Previous message: [maemo-commits] r16212 - projects/haf/branches/hildon-thumbnail/daemonize/thumbs
- Next message: [maemo-commits] r16214 - projects/haf/branches/hildon-thumbnail/daemonize/daemon
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
