X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fplugin.c;h=65e0311aff4a8802fbb3af06834cd221cc98b229;hb=39c1cfe1013d5731f64407881ddf3dc16942063a;hp=216fce15fbf6ea70701e89e7bcb6b4d5510ae84b;hpb=2e88ef3053cf2a12115f78fcd4292266b4c98943;p=framework%2Fconnectivity%2Fconnman.git diff --git a/src/plugin.c b/src/plugin.c index 216fce1..65e0311 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -2,7 +2,7 @@ * * Connection Manager * - * Copyright (C) 2007-2009 Intel Corporation. All rights reserved. + * Copyright (C) 2007-2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -27,12 +27,28 @@ #include +#ifdef CONNMAN_PLUGIN_BUILTIN +#undef CONNMAN_PLUGIN_BUILTIN +#endif + #include "connman.h" +/* + * Plugins that are using libraries with threads and their own mainloop + * will crash on exit. This is a bug inside these libraries, but there is + * nothing much that can be done about it. + */ +#ifdef NEED_THREADS +#define PLUGINFLAG (RTLD_NOW | RTLD_NODELETE) +#else +#define PLUGINFLAG (RTLD_NOW) +#endif + static GSList *plugins = NULL; struct connman_plugin { void *handle; + gboolean active; struct connman_plugin_desc *desc; }; @@ -52,7 +68,8 @@ static gboolean add_plugin(void *handle, struct connman_plugin_desc *desc) return FALSE; if (g_str_equal(desc->version, CONNMAN_VERSION) == FALSE) { - DBG("version mismatch for %s", desc->description); + connman_error("Invalid version %s for %s", desc->version, + desc->description); return FALSE; } @@ -61,26 +78,70 @@ static gboolean add_plugin(void *handle, struct connman_plugin_desc *desc) return FALSE; plugin->handle = handle; + plugin->active = FALSE; plugin->desc = desc; - if (desc->init() < 0) { - g_free(plugin); - return FALSE; - } + __connman_log_enable(desc->debug_start, desc->debug_stop); plugins = g_slist_insert_sorted(plugins, plugin, compare_priority); return TRUE; } +static gboolean check_plugin(struct connman_plugin_desc *desc, + char **patterns, char **excludes) +{ + if (excludes) { + for (; *excludes; excludes++) + if (g_pattern_match_simple(*excludes, desc->name)) + break; + if (*excludes) { + connman_info("Excluding %s", desc->description); + return FALSE; + } + } + + if (patterns) { + for (; *patterns; patterns++) + if (g_pattern_match_simple(*patterns, desc->name)) + break; + if (!*patterns) { + connman_info("Ignoring %s", desc->description); + return FALSE; + } + } + + return TRUE; +} + +#include "builtin.h" + int __connman_plugin_init(const char *pattern, const char *exclude) { + gchar **patterns = NULL; + gchar **excludes = NULL; + GSList *list; GDir *dir; const gchar *file; gchar *filename; + unsigned int i; DBG(""); + if (pattern) + patterns = g_strsplit_set(pattern, ":, ", -1); + + if (exclude) + excludes = g_strsplit_set(exclude, ":, ", -1); + + for (i = 0; __connman_builtin[i]; i++) { + if (check_plugin(__connman_builtin[i], + patterns, excludes) == FALSE) + continue; + + add_plugin(NULL, __connman_builtin[i]); + } + dir = g_dir_open(PLUGINDIR, 0, NULL); if (dir != NULL) { while ((file = g_dir_read_name(dir)) != NULL) { @@ -93,10 +154,10 @@ int __connman_plugin_init(const char *pattern, const char *exclude) filename = g_build_filename(PLUGINDIR, file, NULL); - handle = dlopen(filename, RTLD_NOW); + handle = dlopen(filename, PLUGINFLAG); if (handle == NULL) { - g_warning("Can't load %s: %s", filename, - dlerror()); + connman_error("Can't load %s: %s", + filename, dlerror()); g_free(filename); continue; } @@ -105,21 +166,13 @@ int __connman_plugin_init(const char *pattern, const char *exclude) desc = dlsym(handle, "connman_plugin_desc"); if (desc == NULL) { - g_warning("Can't load symbol: %s", dlerror()); - dlclose(handle); - continue; - } - - if (exclude != NULL && g_pattern_match_simple(exclude, - desc->name) == TRUE) { - DBG("excluding %s", desc->description); + connman_error("Can't load symbol: %s", + dlerror()); dlclose(handle); continue; } - if (pattern != NULL && g_pattern_match_simple(pattern, - desc->name) == FALSE) { - DBG("ignoring %s", desc->description); + if (check_plugin(desc, patterns, excludes) == FALSE) { dlclose(handle); continue; } @@ -131,6 +184,18 @@ int __connman_plugin_init(const char *pattern, const char *exclude) g_dir_close(dir); } + for (list = plugins; list; list = list->next) { + struct connman_plugin *plugin = list->data; + + if (plugin->desc->init() < 0) + continue; + + plugin->active = TRUE; + } + + g_strfreev(patterns); + g_strfreev(excludes); + return 0; } @@ -143,10 +208,11 @@ void __connman_plugin_cleanup(void) for (list = plugins; list; list = list->next) { struct connman_plugin *plugin = list->data; - if (plugin->desc->exit) + if (plugin->active == TRUE && plugin->desc->exit) plugin->desc->exit(); - dlclose(plugin->handle); + if (plugin->handle != NULL) + dlclose(plugin->handle); g_free(plugin); }