Mercurial > pidgin
comparison src/plugin.c @ 6981:abd3c684da31
[gaim-migrate @ 7537]
Fixes some issues with plugin loading. Previously, all protocol plugins were
loaded as soon as they were probed, but this caused issues if they had a
dependency on another plugin. Now, they're all stuffed in a queue, which is
processed after probing, so that all plugins are found. Also, a plugin's
load function can return FALSE to prevent itself from being loaded. I
thought I did that already...
committer: Tailor Script <tailor@pidgin.im>
author | Christian Hammond <chipx86@chipx86.com> |
---|---|
date | Sat, 27 Sep 2003 15:45:49 +0000 |
parents | 7dba3e17cb21 |
children | 083d1e4a9c78 |
comparison
equal
deleted
inserted
replaced
6980:1da447732906 | 6981:abd3c684da31 |
---|---|
53 GaimValue **params; | 53 GaimValue **params; |
54 GaimValue *ret_value; | 54 GaimValue *ret_value; |
55 | 55 |
56 } GaimPluginIpcCommand; | 56 } GaimPluginIpcCommand; |
57 | 57 |
58 static GList *loaded_plugins = NULL; | 58 static GList *loaded_plugins = NULL; |
59 static GList *plugins = NULL; | 59 static GList *plugins = NULL; |
60 static GList *plugin_loaders = NULL; | 60 static GList *plugin_loaders = NULL; |
61 static GList *protocol_plugins = NULL; | 61 static GList *protocol_plugins = NULL; |
62 static GList *load_queue = NULL; | |
62 | 63 |
63 static size_t search_path_count = 0; | 64 static size_t search_path_count = 0; |
64 static char **search_paths = NULL; | 65 static char **search_paths = NULL; |
65 | 66 |
66 static void (*probe_cb)(void *) = NULL; | 67 static void (*probe_cb)(void *) = NULL; |
157 #ifdef GAIM_PLUGINS | 158 #ifdef GAIM_PLUGINS |
158 GaimPlugin *plugin = NULL; | 159 GaimPlugin *plugin = NULL; |
159 GaimPlugin *loader; | 160 GaimPlugin *loader; |
160 gboolean (*gaim_init_plugin)(GaimPlugin *); | 161 gboolean (*gaim_init_plugin)(GaimPlugin *); |
161 | 162 |
163 gaim_debug_misc("plugins", "probing %s\n", filename); | |
162 g_return_val_if_fail(filename != NULL, NULL); | 164 g_return_val_if_fail(filename != NULL, NULL); |
163 | 165 |
164 if (!g_file_test(filename, G_FILE_TEST_EXISTS)) | 166 if (!g_file_test(filename, G_FILE_TEST_EXISTS)) |
165 return NULL; | 167 return NULL; |
166 | 168 |
300 } | 302 } |
301 | 303 |
302 if (dep_list != NULL) | 304 if (dep_list != NULL) |
303 g_list_free(dep_list); | 305 g_list_free(dep_list); |
304 | 306 |
305 if (plugin->native_plugin) { | 307 if (plugin->native_plugin) |
306 if (plugin->info != NULL) { | 308 { |
307 if (plugin->info->load != NULL) | 309 if (plugin->info != NULL && plugin->info->load != NULL) |
308 plugin->info->load(plugin); | 310 { |
311 if (!plugin->info->load(plugin)) | |
312 return FALSE; | |
309 } | 313 } |
310 } | 314 } |
311 else { | 315 else { |
312 GaimPlugin *loader; | 316 GaimPlugin *loader; |
313 GaimPluginLoaderInfo *loader_info; | 317 GaimPluginLoaderInfo *loader_info; |
318 return FALSE; | 322 return FALSE; |
319 | 323 |
320 loader_info = GAIM_PLUGIN_LOADER_INFO(loader); | 324 loader_info = GAIM_PLUGIN_LOADER_INFO(loader); |
321 | 325 |
322 if (loader_info->load != NULL) | 326 if (loader_info->load != NULL) |
323 loader_info->load(plugin); | 327 { |
328 if (!loader_info->load(plugin)) | |
329 return FALSE; | |
330 } | |
324 } | 331 } |
325 | 332 |
326 loaded_plugins = g_list_append(loaded_plugins, plugin); | 333 loaded_plugins = g_list_append(loaded_plugins, plugin); |
327 | 334 |
328 plugin->loaded = TRUE; | 335 plugin->loaded = TRUE; |
435 | 442 |
436 if (gaim_plugin_is_loaded(plugin)) | 443 if (gaim_plugin_is_loaded(plugin)) |
437 gaim_plugin_unload(plugin); | 444 gaim_plugin_unload(plugin); |
438 | 445 |
439 plugins = g_list_remove(plugins, plugin); | 446 plugins = g_list_remove(plugins, plugin); |
447 | |
448 if (load_queue != NULL) | |
449 load_queue = g_list_remove(load_queue, plugin); | |
440 | 450 |
441 if (plugin->info != NULL && plugin->info->dependencies != NULL) | 451 if (plugin->info != NULL && plugin->info->dependencies != NULL) |
442 g_list_free(plugin->info->dependencies); | 452 g_list_free(plugin->info->dependencies); |
443 | 453 |
444 if (plugin->native_plugin) { | 454 if (plugin->native_plugin) { |
767 | 777 |
768 void | 778 void |
769 gaim_plugins_probe(const char *ext) | 779 gaim_plugins_probe(const char *ext) |
770 { | 780 { |
771 #ifdef GAIM_PLUGINS | 781 #ifdef GAIM_PLUGINS |
782 GList *l, *l_next; | |
772 GDir *dir; | 783 GDir *dir; |
773 const gchar *file; | 784 const gchar *file; |
774 gchar *path; | 785 gchar *path; |
775 GaimPlugin *plugin; | 786 GaimPlugin *plugin; |
776 size_t i; | 787 size_t i; |
796 | 807 |
797 g_dir_close(dir); | 808 g_dir_close(dir); |
798 } | 809 } |
799 } | 810 } |
800 | 811 |
812 /* See if we have any plugins waiting to load. */ | |
813 while (load_queue != NULL) | |
814 { | |
815 plugin = (GaimPlugin *)load_queue->data; | |
816 | |
817 load_queue = g_list_remove(load_queue, plugin); | |
818 | |
819 if (plugin == NULL || plugin->info == NULL) | |
820 continue; | |
821 | |
822 if (plugin->info->type == GAIM_PLUGIN_LOADER) | |
823 { | |
824 GList *exts; | |
825 | |
826 /* We'll just load this right now. */ | |
827 if (!gaim_plugin_load(plugin)) | |
828 { | |
829 gaim_plugin_destroy(plugin); | |
830 | |
831 continue; | |
832 } | |
833 | |
834 plugin_loaders = g_list_append(plugin_loaders, plugin); | |
835 | |
836 for (exts = GAIM_PLUGIN_LOADER_INFO(plugin)->exts; | |
837 exts != NULL; | |
838 exts = exts->next) | |
839 { | |
840 gaim_plugins_probe(exts->data); | |
841 } | |
842 } | |
843 else if (plugin->info->type == GAIM_PLUGIN_PROTOCOL) | |
844 { | |
845 | |
846 /* We'll just load this right now. */ | |
847 if (!gaim_plugin_load(plugin)) | |
848 { | |
849 gaim_plugin_destroy(plugin); | |
850 | |
851 continue; | |
852 } | |
853 | |
854 if (GAIM_PLUGIN_PROTOCOL_INFO(plugin)->protocol == GAIM_PROTO_ICQ || | |
855 gaim_find_prpl(GAIM_PLUGIN_PROTOCOL_INFO(plugin)->protocol)) | |
856 { | |
857 /* Nothing to see here--move along, move along */ | |
858 gaim_plugin_destroy(plugin); | |
859 | |
860 continue; | |
861 } | |
862 | |
863 protocol_plugins = g_list_insert_sorted(protocol_plugins, plugin, | |
864 (GCompareFunc)compare_prpl); | |
865 } | |
866 } | |
867 | |
868 if (load_queue != NULL) | |
869 { | |
870 g_list_free(load_queue); | |
871 load_queue = NULL; | |
872 } | |
873 | |
801 if (probe_cb != NULL) | 874 if (probe_cb != NULL) |
802 probe_cb(probe_cb_data); | 875 probe_cb(probe_cb_data); |
803 | 876 |
804 #endif /* GAIM_PLUGINS */ | 877 #endif /* GAIM_PLUGINS */ |
805 } | 878 } |
810 g_return_val_if_fail(plugin != NULL, FALSE); | 883 g_return_val_if_fail(plugin != NULL, FALSE); |
811 | 884 |
812 if (g_list_find(plugins, plugin)) | 885 if (g_list_find(plugins, plugin)) |
813 return TRUE; | 886 return TRUE; |
814 | 887 |
815 /* Special exception for loader plugins. We want them loaded NOW! */ | 888 if (plugin->info->type == GAIM_PLUGIN_LOADER || |
816 if (plugin->info->type == GAIM_PLUGIN_LOADER) { | 889 plugin->info->type == GAIM_PLUGIN_PROTOCOL) |
817 GList *exts; | 890 { |
818 | 891 /* Special exception for loader plugins. We want them loaded NOW! */ |
819 /* We'll just load this right now. */ | 892 load_queue = g_list_append(load_queue, plugin); |
820 if (!gaim_plugin_load(plugin)) { | |
821 | |
822 gaim_plugin_destroy(plugin); | |
823 | |
824 return FALSE; | |
825 } | |
826 | |
827 plugin_loaders = g_list_append(plugin_loaders, plugin); | |
828 | |
829 for (exts = GAIM_PLUGIN_LOADER_INFO(plugin)->exts; | |
830 exts != NULL; | |
831 exts = exts->next) { | |
832 | |
833 gaim_plugins_probe(exts->data); | |
834 } | |
835 } | |
836 else if (plugin->info->type == GAIM_PLUGIN_PROTOCOL) { | |
837 | |
838 /* We'll just load this right now. */ | |
839 if (!gaim_plugin_load(plugin)) { | |
840 | |
841 gaim_plugin_destroy(plugin); | |
842 | |
843 return FALSE; | |
844 } | |
845 | |
846 if (GAIM_PLUGIN_PROTOCOL_INFO(plugin)->protocol == GAIM_PROTO_ICQ || | |
847 gaim_find_prpl(GAIM_PLUGIN_PROTOCOL_INFO(plugin)->protocol)) { | |
848 | |
849 /* Nothing to see here--move along, move along */ | |
850 gaim_plugin_destroy(plugin); | |
851 | |
852 return FALSE; | |
853 } | |
854 | |
855 protocol_plugins = g_list_insert_sorted(protocol_plugins, plugin, | |
856 (GCompareFunc)compare_prpl); | |
857 } | 893 } |
858 | 894 |
859 plugins = g_list_append(plugins, plugin); | 895 plugins = g_list_append(plugins, plugin); |
860 | 896 |
861 return TRUE; | 897 return TRUE; |