diff options
author | lloyd <[email protected]> | 2010-07-27 21:16:29 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2010-07-27 21:16:29 +0000 |
commit | 3531f7981256d7ff45cdcb4c96d4f339c0db1b93 (patch) | |
tree | ef09d804c147888addf6a54ebf28420157f63811 /src | |
parent | f915a1166ed59e0822b8749eeac22b576e0f2223 (diff) |
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).
Diffstat (limited to 'src')
-rw-r--r-- | src/algo_factory/algo_cache.h | 13 | ||||
-rw-r--r-- | src/algo_factory/algo_factory.cpp | 5 |
2 files changed, 14 insertions, 4 deletions
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 @@ -63,11 +63,16 @@ class Algorithm_Cache std::vector<std::string> 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<std::string, std::map<std::string, T*> >::iterator algorithms_iterator; @@ -215,10 +220,10 @@ void Algorithm_Cache<T>::set_preferred_provider(const std::string& algo_spec, } /* -* Algorithm_Cache<T> Destructor +* Clear out the cache */ template<typename T> -Algorithm_Cache<T>::~Algorithm_Cache() +void Algorithm_Cache<T>::clear_cache() { algorithms_iterator algo = algorithms.begin(); @@ -235,7 +240,7 @@ Algorithm_Cache<T>::~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); } |