diff options
Diffstat (limited to 'e-util')
-rw-r--r-- | e-util/e-extensible.c | 24 | ||||
-rw-r--r-- | e-util/e-module.c | 19 |
2 files changed, 30 insertions, 13 deletions
diff --git a/e-util/e-extensible.c b/e-util/e-extensible.c index 6e49e9dba7..a7523deb21 100644 --- a/e-util/e-extensible.c +++ b/e-util/e-extensible.c @@ -94,19 +94,17 @@ extensible_load_extension (GType extension_type, extension_class = g_type_class_ref (extension_type); /* Only load extensions that extend the given extensible object. */ - if (g_type_is_a (extensible_type, extension_class->extensible_type)) { - extension = g_object_new ( - extension_type, "extensible", extensible, NULL); - - extensions = extensible_get_extensions (extensible); - g_ptr_array_add (extensions, extension); - - g_type_class_unref (extension_class); - } else { - /* keep the class referenced forever, later may anyone need it anyway, - and unref it may mean module unload, which breaks static strings - in GType */ - } + if (!g_type_is_a (extensible_type, extension_class->extensible_type)) + goto exit; + + extension = g_object_new ( + extension_type, "extensible", extensible, NULL); + + extensions = extensible_get_extensions (extensible); + g_ptr_array_add (extensions, extension); + +exit: + g_type_class_unref (extension_class); } static void diff --git a/e-util/e-module.c b/e-util/e-module.c index b3e90aac72..46486080d6 100644 --- a/e-util/e-module.c +++ b/e-util/e-module.c @@ -139,6 +139,25 @@ module_load (GTypeModule *type_module) priv->load (type_module); + /* XXX This is a Band-Aid for a design flaw in EExtension. If the + * "extensible_type" member of EExtensionClass is set to a GType + * that hasn't already been registered, then when the extension's + * module is unloaded the GType registration that was triggered + * by setting "extensible_type" will be invalidated and cause + * Evolution to malfunction when the module is loaded again. + * + * Extension modules get loaded and unloaded repeatedly by + * e_extensible_load_extensions(), which temporarily references + * all extension classes and picks out the ones it needs for a + * given EExtensible instance based on the "extensible_type" + * class member. + * + * Making the module resident prevents the aforementioned GType + * registration from being invalidated when the extension class + * is unreferenced. + */ + g_module_make_resident (priv->module); + return TRUE; fail: |