diff options
author | Milan Crha <mcrha@redhat.com> | 2015-11-20 13:03:48 +0100 |
---|---|---|
committer | Milan Crha <mcrha@redhat.com> | 2015-11-20 13:03:48 +0100 |
commit | 07086740ba1c51779e310087f9c77474978a7463 (patch) | |
tree | 6386f34da119b2a91aecfdfc7226c512f6017dd2 | |
parent | 5b89433a5d3d2b73781d8fefc1387be454cd924e (diff) | |
download | evolution-data-server-07086740ba1c51779e310087f9c77474978a7463.tar.gz |
[EDBusServer] Load newly added modules on the fly
This is to cover situation when user installs a new 3rd-party modules
with background processes running, then runs evolution and adds
an account for the installed module, but the Evolution didn't show
anything, until the background processes were restarted.
-rw-r--r-- | addressbook/libedata-book/e-data-book-factory.c | 3 | ||||
-rw-r--r-- | calendar/libedata-cal/e-data-cal-factory.c | 3 | ||||
-rw-r--r-- | libebackend/e-data-factory.c | 18 | ||||
-rw-r--r-- | libebackend/e-dbus-server.c | 65 | ||||
-rw-r--r-- | modules/google-backend/module-google-backend.c | 9 | ||||
-rw-r--r-- | modules/owncloud-backend/module-owncloud-backend.c | 9 | ||||
-rw-r--r-- | services/evolution-addressbook-factory/evolution-addressbook-factory.c | 9 | ||||
-rw-r--r-- | services/evolution-calendar-factory/evolution-calendar-factory.c | 9 | ||||
-rw-r--r-- | services/evolution-user-prompter/evolution-user-prompter.c | 9 |
9 files changed, 115 insertions, 19 deletions
diff --git a/addressbook/libedata-book/e-data-book-factory.c b/addressbook/libedata-book/e-data-book-factory.c index 3dc45740a..7b247deba 100644 --- a/addressbook/libedata-book/e-data-book-factory.c +++ b/addressbook/libedata-book/e-data-book-factory.c @@ -194,5 +194,6 @@ e_data_book_factory_new (GCancellable *cancellable, { return g_initable_new ( E_TYPE_DATA_BOOK_FACTORY, - cancellable, error, NULL); + cancellable, error, + "reload-supported", TRUE, NULL); } diff --git a/calendar/libedata-cal/e-data-cal-factory.c b/calendar/libedata-cal/e-data-cal-factory.c index 57f897fa8..aad79145f 100644 --- a/calendar/libedata-cal/e-data-cal-factory.c +++ b/calendar/libedata-cal/e-data-cal-factory.c @@ -302,5 +302,6 @@ e_data_cal_factory_new (GCancellable *cancellable, return g_initable_new ( E_TYPE_DATA_CAL_FACTORY, - cancellable, error, NULL); + cancellable, error, + "reload-supported", TRUE, NULL); } diff --git a/libebackend/e-data-factory.c b/libebackend/e-data-factory.c index 1f3880e4f..80ecd9dc7 100644 --- a/libebackend/e-data-factory.c +++ b/libebackend/e-data-factory.c @@ -637,11 +637,12 @@ data_factory_subprocess_vanished_cb (GDBusConnection *connection, { DataFactorySubprocessData *sd; DataFactorySubprocessHelper *helper; + EDataFactory *data_factory; EDataFactoryPrivate *priv; const gchar *sender; - guint watched_id; sd = user_data; + data_factory = g_object_ref (sd->data_factory); priv = sd->data_factory->priv; g_mutex_lock (&priv->mutex); @@ -650,8 +651,10 @@ data_factory_subprocess_vanished_cb (GDBusConnection *connection, sd->subprocess_helpers_hash_key); g_mutex_unlock (&priv->mutex); - if (helper == NULL) + if (helper == NULL) { + g_clear_object (&data_factory); return; + } sender = g_dbus_method_invocation_get_sender (sd->invocation); data_factory_connections_remove (sd->data_factory, sender, helper->proxy); @@ -663,12 +666,10 @@ data_factory_subprocess_vanished_cb (GDBusConnection *connection, g_mutex_unlock (&priv->mutex); g_mutex_lock (&priv->subprocess_watched_ids_lock); - watched_id = GPOINTER_TO_UINT (g_hash_table_lookup (priv->subprocess_watched_ids, sd->bus_name)); g_hash_table_remove (priv->subprocess_watched_ids, sd->bus_name); - - if (watched_id > 0) - g_bus_unwatch_name (watched_id); g_mutex_unlock (&priv->subprocess_watched_ids_lock); + + g_clear_object (&data_factory); } static void @@ -1052,7 +1053,7 @@ e_data_factory_init (EDataFactory *data_factory) (GHashFunc) g_str_hash, (GEqualFunc) g_str_equal, (GDestroyNotify) g_free, - (GDestroyNotify) NULL); + (GDestroyNotify) watched_names_value_free); data_factory->priv->connections = g_hash_table_new_full ( (GHashFunc) g_str_hash, @@ -1298,7 +1299,8 @@ data_factory_spawn_subprocess_backend (EDataFactory *data_factory, if (sd) { g_mutex_lock (&priv->subprocess_watched_ids_lock); - g_hash_table_remove (priv->subprocess_watched_ids, sd->bus_name); + if (g_hash_table_remove (priv->subprocess_watched_ids, sd->bus_name)) + watched_id = 0; g_mutex_unlock (&priv->subprocess_watched_ids_lock); } diff --git a/libebackend/e-dbus-server.c b/libebackend/e-dbus-server.c index 646e5926b..a801760ed 100644 --- a/libebackend/e-dbus-server.c +++ b/libebackend/e-dbus-server.c @@ -51,6 +51,8 @@ struct _EDBusServerPrivate { EDBusServerExitCode exit_code; GMutex property_lock; + + GFileMonitor *directory_monitor; }; enum { @@ -157,6 +159,17 @@ dbus_server_finalize (GObject *object) } static void +dbus_server_dispose (GObject *object) +{ + EDBusServer *server = E_DBUS_SERVER (object); + + g_clear_object (&server->priv->directory_monitor); + + /* Chain up to parent's method. */ + G_OBJECT_CLASS (e_dbus_server_parent_class)->dispose (object); +} + +static void dbus_server_constructed (GObject *object) { e_dbus_server_load_modules (E_DBUS_SERVER (object)); @@ -273,6 +286,7 @@ e_dbus_server_class_init (EDBusServerClass *class) object_class = G_OBJECT_CLASS (class); object_class->finalize = dbus_server_finalize; + object_class->dispose = dbus_server_dispose; object_class->constructed = dbus_server_constructed; class->bus_acquired = dbus_server_bus_acquired; @@ -508,6 +522,44 @@ e_dbus_server_release (EDBusServer *server) g_mutex_unlock (&server->priv->property_lock); } +static void +dbus_server_module_directory_changed_cb (GFileMonitor *monitor, + GFile *file, + GFile *other_file, + GFileMonitorEvent event_type, + gpointer user_data) +{ + EDBusServer *server; + + g_return_if_fail (E_IS_DBUS_SERVER (user_data)); + + server = E_DBUS_SERVER (user_data); + + if (event_type == G_FILE_MONITOR_EVENT_CREATED || + event_type == G_FILE_MONITOR_EVENT_DELETED || + event_type == G_FILE_MONITOR_EVENT_MOVED_IN || + event_type == G_FILE_MONITOR_EVENT_MOVED_OUT) { + gchar *filename; + + filename = g_file_get_path (file); + + if (filename && g_str_has_suffix (filename, "." G_MODULE_SUFFIX)) { + if (event_type == G_FILE_MONITOR_EVENT_CREATED || + event_type == G_FILE_MONITOR_EVENT_MOVED_IN) { + EModule *module; + + module = e_module_load_file (filename); + if (module) + g_type_module_unuse ((GTypeModule *) module); + } + + e_dbus_server_quit (server, E_DBUS_SERVER_EXIT_RELOAD); + } + + g_free (filename); + } +} + /** * e_dbus_server_load_modules: * @server: an #EDBusServer @@ -539,6 +591,19 @@ e_dbus_server_load_modules (EDBusServer *server) g_hash_table_add (directories_loaded, (gpointer) directory); G_UNLOCK (directories_loaded); + if (!server->priv->directory_monitor) { + GFile *dir_file; + + dir_file = g_file_new_for_path (class->module_directory); + server->priv->directory_monitor = g_file_monitor_directory (dir_file, G_FILE_MONITOR_WATCH_MOVES, NULL, NULL); + g_clear_object (&dir_file); + + if (server->priv->directory_monitor) { + g_signal_connect (server->priv->directory_monitor, "changed", + G_CALLBACK (dbus_server_module_directory_changed_cb), server); + } + } + if (already_loaded) return; diff --git a/modules/google-backend/module-google-backend.c b/modules/google-backend/module-google-backend.c index 8ab4b2f3b..529f519d9 100644 --- a/modules/google-backend/module-google-backend.c +++ b/modules/google-backend/module-google-backend.c @@ -332,6 +332,8 @@ google_add_found_source (ECollectionBackend *collection, g_return_if_fail (backend_name != NULL); server = e_collection_backend_ref_server (collection); + if (!server) + return; url = soup_uri_to_string (uri, FALSE); identity = g_strconcat (identity_prefix, "::", url, NULL); @@ -510,9 +512,10 @@ google_backend_authenticate_sync (EBackend *backend, server = e_collection_backend_ref_server (collection); - g_hash_table_foreach (known_sources, google_remove_unknown_sources_cb, server); - - g_object_unref (server); + if (server) { + g_hash_table_foreach (known_sources, google_remove_unknown_sources_cb, server); + g_object_unref (server); + } } if (local_error == NULL) { diff --git a/modules/owncloud-backend/module-owncloud-backend.c b/modules/owncloud-backend/module-owncloud-backend.c index 6315d0d5c..238cd7ed7 100644 --- a/modules/owncloud-backend/module-owncloud-backend.c +++ b/modules/owncloud-backend/module-owncloud-backend.c @@ -169,6 +169,8 @@ owncloud_add_found_source (ECollectionBackend *collection, g_return_if_fail (backend_name != NULL); server = e_collection_backend_ref_server (collection); + if (!server) + return; url = soup_uri_to_string (uri, FALSE); identity = g_strconcat (identity_prefix, "::", url, NULL); @@ -376,9 +378,10 @@ owncloud_backend_authenticate_sync (EBackend *backend, server = e_collection_backend_ref_server (collection); - g_hash_table_foreach (known_sources, owncloud_remove_unknown_sources_cb, server); - - g_object_unref (server); + if (server) { + g_hash_table_foreach (known_sources, owncloud_remove_unknown_sources_cb, server); + g_object_unref (server); + } } if (local_error == NULL) { diff --git a/services/evolution-addressbook-factory/evolution-addressbook-factory.c b/services/evolution-addressbook-factory/evolution-addressbook-factory.c index 3d9cdb6f6..08ed33398 100644 --- a/services/evolution-addressbook-factory/evolution-addressbook-factory.c +++ b/services/evolution-addressbook-factory/evolution-addressbook-factory.c @@ -45,6 +45,7 @@ main (gint argc, { GOptionContext *context; EDBusServer *server; + EDBusServerExitCode exit_code; GError *error = NULL; #ifdef G_OS_WIN32 @@ -77,6 +78,7 @@ main (gint argc, e_gdbus_templates_init_main_thread (); + reload: server = e_data_book_factory_new (NULL, &error); if (error != NULL) { @@ -91,10 +93,15 @@ main (gint argc, if (opt_keep_running) e_dbus_server_hold (server); - e_dbus_server_run (server, opt_wait_for_client); + exit_code = e_dbus_server_run (server, opt_wait_for_client); g_object_unref (server); + if (exit_code == E_DBUS_SERVER_EXIT_RELOAD) { + g_debug ("Reloading..."); + goto reload; + } + g_debug ("Bye."); return 0; diff --git a/services/evolution-calendar-factory/evolution-calendar-factory.c b/services/evolution-calendar-factory/evolution-calendar-factory.c index 50ae308bc..ea7d9522b 100644 --- a/services/evolution-calendar-factory/evolution-calendar-factory.c +++ b/services/evolution-calendar-factory/evolution-calendar-factory.c @@ -49,6 +49,7 @@ main (gint argc, { GOptionContext *context; EDBusServer *server; + EDBusServerExitCode exit_code; GError *error = NULL; #ifdef G_OS_WIN32 @@ -85,6 +86,7 @@ main (gint argc, e_gdbus_templates_init_main_thread (); + reload: server = e_data_cal_factory_new (NULL, &error); if (error != NULL) { @@ -99,10 +101,15 @@ main (gint argc, if (opt_keep_running) e_dbus_server_hold (server); - e_dbus_server_run (server, opt_wait_for_client); + exit_code = e_dbus_server_run (server, opt_wait_for_client); g_object_unref (server); + if (exit_code == E_DBUS_SERVER_EXIT_RELOAD) { + g_debug ("Reloading..."); + goto reload; + } + g_debug ("Bye."); return 0; diff --git a/services/evolution-user-prompter/evolution-user-prompter.c b/services/evolution-user-prompter/evolution-user-prompter.c index b97778e3a..21d1ad244 100644 --- a/services/evolution-user-prompter/evolution-user-prompter.c +++ b/services/evolution-user-prompter/evolution-user-prompter.c @@ -39,6 +39,7 @@ main (gint argc, { GOptionContext *context; EDBusServer *server; + EDBusServerExitCode exit_code; GError *error = NULL; #ifdef G_OS_WIN32 @@ -66,6 +67,7 @@ main (gint argc, e_gdbus_templates_init_main_thread (); + reload: server = e_user_prompter_server_new (); g_signal_connect ( server, "prompt", @@ -78,10 +80,15 @@ main (gint argc, if (opt_keep_running) e_dbus_server_hold (server); - e_dbus_server_run (server, TRUE); + exit_code = e_dbus_server_run (server, TRUE); g_object_unref (server); + if (exit_code == E_DBUS_SERVER_EXIT_RELOAD) { + g_debug ("Reloading..."); + goto reload; + } + g_debug ("Bye."); return 0; |