Mercurial > pidgin.yaz
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; |
