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;