diff options
author | Christian Grothoff <christian@grothoff.org> | 2018-03-12 14:07:42 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2018-04-02 14:29:44 +0200 |
commit | 7a20062bafed42f937c5388aed09042aad7014c0 (patch) | |
tree | f47da67f2a23bb79779e6b0dafc7d8b7b6e3f7c2 /src/wire | |
parent | 3e191f3b080f692bbb80c66f5c24736955f3f46d (diff) |
modify wire plugin load logic to use reference counting
Diffstat (limited to 'src/wire')
-rw-r--r-- | src/wire/wire.c | 81 |
1 files changed, 79 insertions, 2 deletions
diff --git a/src/wire/wire.c b/src/wire/wire.c index c799334f9..58180b7b1 100644 --- a/src/wire/wire.c +++ b/src/wire/wire.c @@ -1,6 +1,6 @@ /* This file is part of TALER - (C) 2015, 2016, 2017 GNUnet e.V. + (C) 2015, 2016, 2017, 2018 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -23,6 +23,50 @@ #include "taler_util.h" #include "taler_wire_lib.h" + +/** + * A wire plugin that we have loaded. + */ +struct WirePlugin +{ + /** + * We keep these in a DLL. + */ + struct WirePlugin *next; + + /** + * We keep these in a DLL. + */ + struct WirePlugin *prev; + + /** + * Type of this wire plugin. + */ + char *type; + + /** + * Wire plugin + */ + struct TALER_WIRE_Plugin *plugin; + + /** + * Reference counter for the plugin. + */ + unsigned int rc; +}; + + +/** + * Head of the DLL of loaded wire plugins. + */ +static struct WirePlugin *wp_head; + +/** + * Tail of the DLL of loaded wire plugins. + */ +static struct WirePlugin *wp_tail; + + /** * Load a WIRE plugin. * @@ -36,7 +80,15 @@ TALER_WIRE_plugin_load (const struct GNUNET_CONFIGURATION_Handle *cfg, { char *lib_name; struct TALER_WIRE_Plugin *plugin; - + struct WirePlugin *wp; + + for (wp = wp_head; NULL != wp; wp = wp->next) + if (0 == strcasecmp (plugin_name, + wp->type)) + { + wp->rc++; + return wp->plugin; + } (void) GNUNET_asprintf (&lib_name, "libtaler_plugin_wire_%s", plugin_name); @@ -46,6 +98,15 @@ TALER_WIRE_plugin_load (const struct GNUNET_CONFIGURATION_Handle *cfg, plugin->library_name = lib_name; else GNUNET_free (lib_name); + if (NULL == plugin) + return NULL; + wp = GNUNET_new (struct WirePlugin); + wp->plugin = plugin; + wp->type = GNUNET_strdup (plugin_name); + GNUNET_CONTAINER_DLL_insert (wp_head, + wp_tail, + wp); + wp->rc = 1; return plugin; } @@ -58,10 +119,26 @@ TALER_WIRE_plugin_load (const struct GNUNET_CONFIGURATION_Handle *cfg, void TALER_WIRE_plugin_unload (struct TALER_WIRE_Plugin *plugin) { + struct WirePlugin *wp; char *lib_name; if (NULL == plugin) return; + for (wp = wp_head; NULL != wp; wp = wp->next) + { + if (plugin == wp->plugin) + { + wp->rc--; + if (0 < wp->rc) + return; + GNUNET_CONTAINER_DLL_remove (wp_head, + wp_tail, + wp); + GNUNET_free (wp->type); + GNUNET_free (wp); + break; + } + } lib_name = plugin->library_name; GNUNET_assert (NULL == GNUNET_PLUGIN_unload (lib_name, plugin)); |