aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlloyd <[email protected]>2010-07-27 21:16:29 +0000
committerlloyd <[email protected]>2010-07-27 21:16:29 +0000
commit3531f7981256d7ff45cdcb4c96d4f339c0db1b93 (patch)
treeef09d804c147888addf6a54ebf28420157f63811
parentf915a1166ed59e0822b8749eeac22b576e0f2223 (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).
-rw-r--r--src/algo_factory/algo_cache.h13
-rw-r--r--src/algo_factory/algo_factory.cpp5
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);
}