diff --git a/ChangeLog b/ChangeLog index ecf1e77dd8dddef64107485d57635fec132c1507..ab00f47ef32758fefb8f43ec4fcd391e1cda114e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2006-02-09 Benedikt Meurer <benny@xfce.org> + + * thunarx/thunarx-provider-factory.c: Initialize the factory on demand. + * thunar-vfs/thunar-vfs-scandir.c(thunar_vfs_scandir_collect_fast): Use + a larger buffer to speed up loading large directories. + * thunar-vfs/thunar-vfs-mime-database.c: Initialize the MIME desktop + stores on demand. + 2006-02-09 Benedikt Meurer <benny@xfce.org> * thunar/thunar-file.h: Use cast checks instead of type checks here, as diff --git a/thunar-vfs/thunar-vfs-mime-database.c b/thunar-vfs/thunar-vfs-mime-database.c index 2f1916485b1244fa97ddbcbe54254d7c90f4b76c..c84f2bd76a9f507068bdea6da92bde9a50fcbdb3 100644 --- a/thunar-vfs/thunar-vfs-mime-database.c +++ b/thunar-vfs/thunar-vfs-mime-database.c @@ -251,9 +251,6 @@ thunar_vfs_mime_database_init (ThunarVfsMimeDatabase *database) /* initialize the MIME providers */ thunar_vfs_mime_database_initialize_providers (database); - /* initialize the MIME desktop stores */ - thunar_vfs_mime_database_initialize_stores (database); - /* connect emission hook for the "changed" signal on the GtkIconTheme class. We use the emission * hook to reset the icon names of all mime infos at once. */ @@ -262,13 +259,6 @@ thunar_vfs_mime_database_init (ThunarVfsMimeDatabase *database) 0, thunar_vfs_mime_database_icon_theme_changed, database, NULL); g_type_class_unref (klass); - - /* start the timer, which invokes thunar-vfs-mime-cleaner from time to time to cleanup the - * user's mime database directories, so we don't keep old junk around for too long. - */ - database->cleanup_timer_id = g_timeout_add_full (G_PRIORITY_LOW, THUNAR_VFS_MIME_DATABASE_CLEANUP_INTERVAL, - thunar_vfs_mime_database_cleanup_timer, database, - thunar_vfs_mime_database_cleanup_timer_destroy); } @@ -279,14 +269,15 @@ thunar_vfs_mime_database_finalize (GObject *object) ThunarVfsMimeDatabase *database = THUNAR_VFS_MIME_DATABASE (object); /* cancel any pending cleanup timer */ - if (G_LIKELY (database->cleanup_timer_id >= 0)) + if (G_LIKELY (database->cleanup_timer_id > 0)) g_source_remove (database->cleanup_timer_id); /* remove the "changed" emission hook from the GtkIconTheme class */ g_signal_remove_emission_hook (g_signal_lookup ("changed", GTK_TYPE_ICON_THEME), database->changed_hook_id); - /* shutdown the MIME desktop stores */ - thunar_vfs_mime_database_shutdown_stores (database); + /* shutdown the MIME desktop stores (if initialized) */ + if (G_LIKELY (database->stores != NULL)) + thunar_vfs_mime_database_shutdown_stores (database); /* release the MIME providers */ thunar_vfs_mime_database_shutdown_providers (database); @@ -707,6 +698,17 @@ thunar_vfs_mime_database_initialize_stores (ThunarVfsMimeDatabase *database) g_free (path); } g_strfreev (basedirs); + + /* launch the clean up timer if it's not already running */ + if (G_LIKELY (database->cleanup_timer_id == 0)) + { + /* start the timer, which invokes thunar-vfs-mime-cleaner from time to time to cleanup the + * user's mime database directories, so we don't keep old junk around for too long. + */ + database->cleanup_timer_id = g_timeout_add_full (G_PRIORITY_LOW, THUNAR_VFS_MIME_DATABASE_CLEANUP_INTERVAL, + thunar_vfs_mime_database_cleanup_timer, database, + thunar_vfs_mime_database_cleanup_timer_destroy); + } } @@ -916,7 +918,7 @@ thunar_vfs_mime_database_cleanup_timer (gpointer user_data) static void thunar_vfs_mime_database_cleanup_timer_destroy (gpointer user_data) { - THUNAR_VFS_MIME_DATABASE (user_data)->cleanup_timer_id = -1; + THUNAR_VFS_MIME_DATABASE (user_data)->cleanup_timer_id = 0; } @@ -1313,6 +1315,10 @@ thunar_vfs_mime_database_get_applications (ThunarVfsMimeDatabase *database, /* determine the mime infos for info */ infos = thunar_vfs_mime_database_get_infos_for_info_locked (database, info); + /* be sure to initialize the MIME desktop stores first */ + if (G_UNLIKELY (database->stores == NULL)) + thunar_vfs_mime_database_initialize_stores (database); + /* lookup the default applications for the infos */ for (lp = infos; lp != NULL; lp = lp->next) { @@ -1424,6 +1430,10 @@ thunar_vfs_mime_database_get_default_application (ThunarVfsMimeDatabase *databas g_mutex_lock (database->lock); + /* be sure to initialize the MIME desktop stores first */ + if (G_UNLIKELY (database->stores == NULL)) + thunar_vfs_mime_database_initialize_stores (database); + infos = thunar_vfs_mime_database_get_infos_for_info_locked (database, info); for (lp = infos; application == NULL && lp != NULL; lp = lp->next) { @@ -1515,6 +1525,10 @@ thunar_vfs_mime_database_set_default_application (ThunarVfsMimeDatabase *data /* acquire the lock on the database */ g_mutex_lock (database->lock); + /* be sure to initialize the MIME desktop stores first */ + if (G_UNLIKELY (database->stores == NULL)) + thunar_vfs_mime_database_initialize_stores (database); + /* grab the user's desktop applications store */ store = database->stores; diff --git a/thunar-vfs/thunar-vfs-scandir.c b/thunar-vfs/thunar-vfs-scandir.c index 70fbd95158e880e50033e663deaa939cb56e11e5..91be6dc5e26194574cbb85c15fceedad3351e177 100644 --- a/thunar-vfs/thunar-vfs-scandir.c +++ b/thunar-vfs/thunar-vfs-scandir.c @@ -158,7 +158,7 @@ thunar_vfs_scandir_collect_fast (ThunarVfsScandirHandle *handle, } /* calculate the directory buffer size */ - dlen = statb.st_blksize * 4; + dlen = statb.st_blksize * 8; if (G_UNLIKELY ((dlen % DIRBLKSIZ) != 0)) dlen = ((dlen + DIRBLKSIZ - 1) / DIRBLKSIZ) * DIRBLKSIZ; if (G_UNLIKELY (dlen < sizeof (struct statfs))) diff --git a/thunarx/thunarx-provider-factory.c b/thunarx/thunarx-provider-factory.c index aed749e89733c43bc3d2d8282d367c966ff33422..ab92a564016e8c82d94171242e55584e1665ce51 100644 --- a/thunarx/thunarx-provider-factory.c +++ b/thunarx/thunarx-provider-factory.c @@ -1,6 +1,6 @@ /* $Id$ */ /*- - * Copyright (c) 2005 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2005-206 Benedikt Meurer <benny@xfce.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -38,10 +38,10 @@ static void thunarx_provider_factory_class_init (ThunarxProviderFactoryClass *klass); -static void thunarx_provider_factory_init (ThunarxProviderFactory *manager); static void thunarx_provider_factory_finalize (GObject *object); -static void thunarx_provider_factory_add (ThunarxProviderFactory *manager, +static void thunarx_provider_factory_add (ThunarxProviderFactory *factory, ThunarxProviderModule *module); +static GList *thunarx_provider_factory_load_modules (ThunarxProviderFactory *factory); static gboolean thunarx_provider_factory_timer (gpointer user_data); static void thunarx_provider_factory_timer_destroy (gpointer user_data); @@ -92,7 +92,7 @@ thunarx_provider_factory_get_type (void) NULL, sizeof (ThunarxProviderFactory), 0, - (GInstanceInitFunc) thunarx_provider_factory_init, + NULL, NULL, }; @@ -119,10 +119,54 @@ thunarx_provider_factory_class_init (ThunarxProviderFactoryClass *klass) static void -thunarx_provider_factory_init (ThunarxProviderFactory *factory) +thunarx_provider_factory_finalize (GObject *object) +{ + ThunarxProviderFactory *factory = THUNARX_PROVIDER_FACTORY (object); + gint n; + + /* stop the "provider cache" cleanup timer */ + if (G_LIKELY (factory->timer_id > 0)) + g_source_remove (factory->timer_id); + + /* release provider infos */ + for (n = 0; n < factory->n_infos; ++n) + if (factory->infos[n].provider != NULL) + g_object_unref (factory->infos[n].provider); + g_free (factory->infos); + + (*G_OBJECT_CLASS (thunarx_provider_factory_parent_class)->finalize) (object); +} + + + +static void +thunarx_provider_factory_add (ThunarxProviderFactory *factory, + ThunarxProviderModule *module) +{ + const GType *types; + gint n_types; + + /* determines the types provided by the module */ + thunarx_provider_module_list_types (module, &types, &n_types); + + /* add the types provided by the extension */ + factory->infos = g_renew (ThunarxProviderInfo, factory->infos, factory->n_infos + n_types); + for (; n_types-- > 0; ++types) + { + factory->infos[factory->n_infos].provider = NULL; + factory->infos[factory->n_infos].type = *types; + ++factory->n_infos; + } +} + + + +static GList* +thunarx_provider_factory_load_modules (ThunarxProviderFactory *factory) { ThunarxProviderModule *module; const gchar *name; + GList *modules = NULL; GList *lp; GDir *dp; @@ -155,7 +199,7 @@ thunarx_provider_factory_init (ThunarxProviderFactory *factory) { /* allocate the new module and add it to our list */ module = thunarx_provider_module_new (name); - thunarx_provider_modules = g_list_append (thunarx_provider_modules, module); + thunarx_provider_modules = g_list_prepend (thunarx_provider_modules, module); } /* try to load the module */ @@ -164,9 +208,8 @@ thunarx_provider_factory_init (ThunarxProviderFactory *factory) /* add the types provided by the module */ thunarx_provider_factory_add (factory, module); - /* don't unuse the type plugin if it should be resident in memory */ - if (G_LIKELY (!thunarx_provider_plugin_get_resident (THUNARX_PROVIDER_PLUGIN (module)))) - g_type_module_unuse (G_TYPE_MODULE (module)); + /* add the module to our list */ + modules = g_list_prepend (modules, module); } } } @@ -174,53 +217,7 @@ thunarx_provider_factory_init (ThunarxProviderFactory *factory) g_dir_close (dp); } - /* start the "provider cache" cleanup timer */ - factory->timer_id = g_timeout_add_full (G_PRIORITY_LOW, THUNARX_PROVIDER_FACTORY_INTERVAL, - thunarx_provider_factory_timer, factory, - thunarx_provider_factory_timer_destroy); -} - - - -static void -thunarx_provider_factory_finalize (GObject *object) -{ - ThunarxProviderFactory *factory = THUNARX_PROVIDER_FACTORY (object); - gint n; - - /* stop the "provider cache" cleanup timer */ - if (G_LIKELY (factory->timer_id >= 0)) - g_source_remove (factory->timer_id); - - /* release provider infos */ - for (n = 0; n < factory->n_infos; ++n) - if (factory->infos[n].provider != NULL) - g_object_unref (factory->infos[n].provider); - g_free (factory->infos); - - (*G_OBJECT_CLASS (thunarx_provider_factory_parent_class)->finalize) (object); -} - - - -static void -thunarx_provider_factory_add (ThunarxProviderFactory *factory, - ThunarxProviderModule *module) -{ - const GType *types; - gint n_types; - - /* determines the types provided by the module */ - thunarx_provider_module_list_types (module, &types, &n_types); - - /* add the types provided by the extension */ - factory->infos = g_renew (ThunarxProviderInfo, factory->infos, factory->n_infos + n_types); - for (; n_types-- > 0; ++types) - { - factory->infos[factory->n_infos].provider = NULL; - factory->infos[factory->n_infos].type = *types; - ++factory->n_infos; - } + return modules; } @@ -255,7 +252,7 @@ thunarx_provider_factory_timer (gpointer user_data) static void thunarx_provider_factory_timer_destroy (gpointer user_data) { - THUNARX_PROVIDER_FACTORY (user_data)->timer_id = -1; + THUNARX_PROVIDER_FACTORY (user_data)->timer_id = 0; } @@ -316,8 +313,23 @@ thunarx_provider_factory_list_providers (ThunarxProviderFactory *factory, { ThunarxProviderInfo *info; GList *providers = NULL; + GList *modules = NULL; + GList *lp; gint n; + /* check if the cleanup timer is running (and thereby the factory is initialized) */ + if (G_UNLIKELY (factory->timer_id == 0)) + { + /* load all available modules (and thereby initialize the factory) */ + modules = thunarx_provider_factory_load_modules (factory); + + /* start the "provider cache" cleanup timer */ + factory->timer_id = g_timeout_add_full (G_PRIORITY_LOW, THUNARX_PROVIDER_FACTORY_INTERVAL, + thunarx_provider_factory_timer, factory, + thunarx_provider_factory_timer_destroy); + } + + /* determine all available providers for the type */ for (info = factory->infos, n = factory->n_infos; --n >= 0; ++info) if (G_LIKELY (g_type_is_a (info->type, type))) { @@ -336,6 +348,15 @@ thunarx_provider_factory_list_providers (ThunarxProviderFactory *factory, providers = g_list_append (providers, info->provider); } + /* check if we were initialized by this method invocation */ + if (G_UNLIKELY (modules != NULL)) + { + /* unload all non-persistent modules */ + for (lp = modules; lp != NULL; lp = lp->next) + if (!thunarx_provider_plugin_get_resident (lp->data)) + g_type_module_unuse (G_TYPE_MODULE (lp->data)); + } + return providers; }