diff options
author | Tobias Brunner <tobias@strongswan.org> | 2012-05-23 17:41:11 +0200 |
---|---|---|
committer | Tobias Brunner <tobias@strongswan.org> | 2012-05-23 17:50:05 +0200 |
commit | 9eac6106d07ea176eb431d924b1762c79a35a8a0 (patch) | |
tree | 4bbaaafe3e58975cf60ccd393aaf7c6ac8f536fe /src/libstrongswan/plugins/plugin_loader.c | |
parent | a9cfd29c10c7a9c16167023c9470255eb1eecbb4 (diff) | |
download | strongswan-9eac6106d07ea176eb431d924b1762c79a35a8a0.tar.bz2 strongswan-9eac6106d07ea176eb431d924b1762c79a35a8a0.tar.xz |
Use a hashtable to check for already loaded plugin features.
Diffstat (limited to 'src/libstrongswan/plugins/plugin_loader.c')
-rw-r--r-- | src/libstrongswan/plugins/plugin_loader.c | 57 |
1 files changed, 37 insertions, 20 deletions
diff --git a/src/libstrongswan/plugins/plugin_loader.c b/src/libstrongswan/plugins/plugin_loader.c index c1a929bd6..3ff05e483 100644 --- a/src/libstrongswan/plugins/plugin_loader.c +++ b/src/libstrongswan/plugins/plugin_loader.c @@ -25,6 +25,7 @@ #include <debug.h> #include <library.h> #include <integrity_checker.h> +#include <utils/hashtable.h> #include <utils/linked_list.h> #include <plugins/plugin.h> @@ -47,6 +48,11 @@ struct private_plugin_loader_t { linked_list_t *plugins; /** + * Hashtable for loaded features, as plugin_feature_t + */ + hashtable_t *loaded_features; + + /** * List of names of loaded plugins */ char *loaded_plugins; @@ -294,32 +300,14 @@ static bool dependencies_satisfied(private_plugin_loader_t *this, /* first entry is provided feature, followed by dependencies */ for (i = 1; i < count; i++) { - enumerator_t *entries, *loaded; - plugin_feature_t *feature; - plugin_entry_t *current; - bool found = FALSE; + plugin_feature_t *found; if (features[i].kind != FEATURE_DEPENDS && features[i].kind != FEATURE_SDEPEND) { /* end of dependencies */ break; } - entries = this->plugins->create_enumerator(this->plugins); - while (entries->enumerate(entries, ¤t)) - { - loaded = current->loaded->create_enumerator(current->loaded); - while (loaded->enumerate(loaded, &feature)) - { - if (plugin_feature_matches(&features[i], feature)) - { - found = TRUE; - break; - } - } - loaded->destroy(loaded); - } - entries->destroy(entries); - + found = this->loaded_features->get(this->loaded_features, &features[i]); if (!found && (features[i].kind != FEATURE_SDEPEND || soft)) { if (report) @@ -411,6 +399,8 @@ static int load_features(private_plugin_loader_t *this, bool soft, bool report) { if (plugin_feature_load(entry->plugin, feature, reg)) { + this->loaded_features->put(this->loaded_features, + feature, feature); entry->loaded->insert_last(entry->loaded, feature); loaded++; } @@ -439,6 +429,28 @@ static int load_features(private_plugin_loader_t *this, bool soft, bool report) } /** + * Since plugin_feature_t objectss are loosely matched we can't use remove() to + * remove them from the hashtable. + */ +static void unregister_loaded_feature(private_plugin_loader_t *this, + plugin_feature_t *feature) +{ + plugin_feature_t *current; + enumerator_t *enumerator; + + enumerator = this->loaded_features->create_enumerator(this->loaded_features); + while (enumerator->enumerate(enumerator, ¤t, NULL)) + { + if (current == feature) + { + this->loaded_features->remove_at(this->loaded_features, enumerator); + break; + } + } + enumerator->destroy(enumerator); +} + +/** * Try to unload plugin features on which is not depended anymore */ static int unload_features(private_plugin_loader_t *this, plugin_entry_t *entry) @@ -456,6 +468,7 @@ static int unload_features(private_plugin_loader_t *this, plugin_entry_t *entry) !dependency_required(this, feature) && plugin_feature_unload(entry->plugin, feature, reg)) { + unregister_loaded_feature(this, feature); entry->loaded->remove(entry->loaded, feature, NULL); unloaded++; } @@ -665,6 +678,7 @@ METHOD(plugin_loader_t, destroy, void, private_plugin_loader_t *this) { unload(this); + this->loaded_features->destroy(this->loaded_features); this->plugins->destroy(this->plugins); free(this->loaded_plugins); free(this); @@ -687,6 +701,9 @@ plugin_loader_t *plugin_loader_create() .destroy = _destroy, }, .plugins = linked_list_create(), + .loaded_features = hashtable_create( + (hashtable_hash_t)plugin_feature_hash, + (hashtable_equals_t)plugin_feature_matches, 64), ); return &this->public; |