aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2015-12-04 09:27:10 -0500
committerJack Lloyd <[email protected]>2015-12-04 09:27:10 -0500
commit760c8434227be7cea3ac315b3d5610e959af600e (patch)
treef93d13d28b07d046027cc2e61c0e64b641076b84 /src/lib
parent6ffc6d4da50bc23e0d5ba039fe1e18825513a5f2 (diff)
parent12bd679149183d59927c433eb95fbc4f68cfd4b3 (diff)
Merge pull request #321 from matejk/fix_algo_registry_locking_windows
Algo_Registry: Use CRITICAL_SECTION on Windows to prevent hang during initialization
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/base/algo_registry.h60
1 files changed, 54 insertions, 6 deletions
diff --git a/src/lib/base/algo_registry.h b/src/lib/base/algo_registry.h
index e16522d94..eec1ce88d 100644
--- a/src/lib/base/algo_registry.h
+++ b/src/lib/base/algo_registry.h
@@ -1,5 +1,6 @@
/*
* (C) 2014,2015 Jack Lloyd
+* (C) 2015 Matej Kenda
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -16,8 +17,48 @@
#include <string>
#include <unordered_map>
+#if defined(_MSC_VER) && (_MSC_VER <= 1800)
+
+ #define BOTAN_WORKAROUND_GH_321
+ #define NOMINMAX 1
+ #define WIN32_LEAN_AND_MEAN 1
+ #include <Windows.h>
+
+#endif
+
namespace Botan {
+#if defined(BOTAN_WORKAROUND_GH_321)
+
+class WinCS_Mutex
+ {
+ public:
+ WinCS_Mutex()
+ {
+ InitializeCriticalSection(&m_cs);
+ }
+
+ ~WinCS_Mutex()
+ {
+ DeleteCriticalSection(&m_cs);
+ }
+
+ void lock()
+ {
+ EnterCriticalSection(&m_cs);
+ }
+
+ void unlock()
+ {
+ LeaveCriticalSection(&m_cs);
+ }
+
+ private:
+ CRITICAL_SECTION m_cs;
+ };
+
+#endif
+
template<typename T>
class Algo_Registry
{
@@ -34,14 +75,14 @@ class Algo_Registry
void add(const std::string& name, const std::string& provider, maker_fn fn, byte pref)
{
- std::unique_lock<std::mutex> lock(m_mutex);
+ std::lock_guard<mutex> lock(m_mutex);
if(!m_algo_info[name].add_provider(provider, fn, pref))
throw std::runtime_error("Duplicated registration of " + name + "/" + provider);
}
std::vector<std::string> providers_of(const Spec& spec)
{
- std::unique_lock<std::mutex> lock(m_mutex);
+ std::lock_guard<mutex> lock(m_mutex);
auto i = m_algo_info.find(spec.algo_name());
if(i != m_algo_info.end())
return i->second.providers();
@@ -50,7 +91,7 @@ class Algo_Registry
void set_provider_preference(const Spec& spec, const std::string& provider, byte pref)
{
- std::unique_lock<std::mutex> lock(m_mutex);
+ std::lock_guard<mutex> lock(m_mutex);
auto i = m_algo_info.find(spec.algo_name());
if(i != m_algo_info.end())
i->second.set_pref(provider, pref);
@@ -92,11 +133,18 @@ class Algo_Registry
};
private:
- Algo_Registry() {}
+
+#if defined(BOTAN_WORKAROUND_GH_321)
+ using mutex = WinCS_Mutex;
+#else
+ using mutex = std::mutex;
+#endif
+
+ Algo_Registry() { }
std::vector<maker_fn> get_makers(const Spec& spec, const std::string& provider)
{
- std::unique_lock<std::mutex> lock(m_mutex);
+ std::lock_guard<mutex> lock(m_mutex);
return m_algo_info[spec.algo_name()].get_makers(provider);
}
@@ -158,7 +206,7 @@ class Algo_Registry
std::unordered_map<std::string, maker_fn> m_maker_fns;
};
- std::mutex m_mutex;
+ mutex m_mutex;
std::unordered_map<std::string, Algo_Info> m_algo_info;
};