From 3531f7981256d7ff45cdcb4c96d4f339c0db1b93 Mon Sep 17 00:00:00 2001 From: lloyd Date: Tue, 27 Jul 2010 21:16:29 +0000 Subject: There was an interesting bug affecting dynamically loaded engines. The library initializer runs some self tests; this brings objects for a few select types (AES, SHA-1, etc) into the caches. Later on, when we add a dynamic engine, the engines aren't requeried because the cache has hits. So, for instance an dlopen'ed engine that provided AES-128 would not actually be used unless you called on the algo factory with a provider of "blah" - even using set_preferred_provider would have no effect, because that's just a request. Add a new function to Algorithm_Cache, clear_cache, which just deletes everything that is currently loaded (this is 90% of the destructor). Then call this on each cache in Algorithm_Factory when a new Engine is loaded. In normal use, this should be very fast because on init the engines are loaded one after another so clear_cache() won't do much work at all, but it ensures that if you load an engine later on in runtime it will always be found. It does have the downside that the app will then requery each Engine for each new algo after this point, but I think typically loading a dynamic engine will happen very early on so this won't be too much of a hassle. (And even if it happens in the middle of execution, everything still works, it just means some overhead the first time you ask for algo X). --- src/algo_factory/algo_cache.h | 13 +++++++++---- src/algo_factory/algo_factory.cpp | 5 +++++ 2 files changed, 14 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/algo_factory/algo_cache.h b/src/algo_factory/algo_cache.h index 376af130b..4606cac23 100644 --- a/src/algo_factory/algo_cache.h +++ b/src/algo_factory/algo_cache.h @@ -62,12 +62,17 @@ class Algorithm_Cache */ std::vector providers_of(const std::string& algo_name); + /** + * Clear the cache + */ + void clear_cache(); + /** * Constructor * @param m a mutex to serialize internal access */ Algorithm_Cache(Mutex* m) : mutex(m) {} - ~Algorithm_Cache(); + ~Algorithm_Cache() { clear_cache(); delete mutex; } private: typedef typename std::map >::iterator algorithms_iterator; @@ -215,10 +220,10 @@ void Algorithm_Cache::set_preferred_provider(const std::string& algo_spec, } /* -* Algorithm_Cache Destructor +* Clear out the cache */ template -Algorithm_Cache::~Algorithm_Cache() +void Algorithm_Cache::clear_cache() { algorithms_iterator algo = algorithms.begin(); @@ -235,7 +240,7 @@ Algorithm_Cache::~Algorithm_Cache() ++algo; } - delete mutex; + algorithms.clear(); } } diff --git a/src/algo_factory/algo_factory.cpp b/src/algo_factory/algo_factory.cpp index 526ad1beb..16ac589a1 100644 --- a/src/algo_factory/algo_factory.cpp +++ b/src/algo_factory/algo_factory.cpp @@ -110,6 +110,11 @@ Algorithm_Factory::~Algorithm_Factory() void Algorithm_Factory::add_engine(Engine* engine) { + block_cipher_cache->clear_cache(); + stream_cipher_cache->clear_cache(); + hash_cache->clear_cache(); + mac_cache->clear_cache(); + engines.push_back(engine); } -- cgit v1.2.3