aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/base
diff options
context:
space:
mode:
authorMatej Kenda <[email protected]>2015-11-02 14:39:40 +0100
committerMatej Kenda <[email protected]>2015-11-03 08:26:54 +0100
commit1ec38dc7e6de206c0da6f8e0bd1605cc022a1a0c (patch)
treeadab66ddb5b8e49e15d6a140002e8f86808935f1 /src/lib/base
parent50878a88d285344949f3257a4a9fa0137af2b5a2 (diff)
Algo_Registry: Use CRITICAL_SECTION instead of std::mutex to prevent hang in DllMain when initialising global constants.
Diffstat (limited to 'src/lib/base')
-rw-r--r--src/lib/base/algo_registry.h54
1 files changed, 49 insertions, 5 deletions
diff --git a/src/lib/base/algo_registry.h b/src/lib/base/algo_registry.h
index e16522d94..2f53d144e 100644
--- a/src/lib/base/algo_registry.h
+++ b/src/lib/base/algo_registry.h
@@ -16,8 +16,36 @@
#include <string>
#include <unordered_map>
+#if defined(_MSC_VER) && (_MSC_VER <= 1800)
+ #define NOMINMAX 1
+ #define WIN32_LEAN_AND_MEAN 1
+ #include <Windows.h>
+#endif
+
namespace Botan {
+#if defined(_MSC_VER) && (_MSC_VER <= 1800)
+class Windows_Lock
+ {
+ public:
+ Windows_Lock(CRITICAL_SECTION& cs): m_cs(cs)
+ {
+ EnterCriticalSection(&m_cs);
+ }
+
+ ~Windows_Lock()
+ {
+ LeaveCriticalSection(&m_cs);
+ }
+ private:
+ CRITICAL_SECTION& m_cs;
+ };
+
+ #define ALGO_REGISTRY_LOCK(_x) Windows_Lock lock(_x)
+#else
+ #define ALGO_REGISTRY_LOCK(_x) std::unique_lock<std::mutex> lock(_x)
+#endif
+
template<typename T>
class Algo_Registry
{
@@ -34,14 +62,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);
+ ALGO_REGISTRY_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);
+ ALGO_REGISTRY_LOCK(m_mutex);
auto i = m_algo_info.find(spec.algo_name());
if(i != m_algo_info.end())
return i->second.providers();
@@ -50,7 +78,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);
+ ALGO_REGISTRY_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 +120,23 @@ class Algo_Registry
};
private:
- Algo_Registry() {}
+ Algo_Registry()
+ {
+#if defined(_MSC_VER) && (_MSC_VER <= 1800)
+ InitializeCriticalSection(&m_mutex);
+#endif
+ }
+
+#if defined(_MSC_VER) && (_MSC_VER <= 1800)
+ ~Algo_Registry()
+ {
+ DeleteCriticalSection(&m_mutex);
+ }
+#endif
std::vector<maker_fn> get_makers(const Spec& spec, const std::string& provider)
{
- std::unique_lock<std::mutex> lock(m_mutex);
+ ALGO_REGISTRY_LOCK(m_mutex);
return m_algo_info[spec.algo_name()].get_makers(provider);
}
@@ -158,7 +198,11 @@ class Algo_Registry
std::unordered_map<std::string, maker_fn> m_maker_fns;
};
+#if defined(_MSC_VER) && (_MSC_VER <= 1800)
+ CRITICAL_SECTION m_mutex;
+#else
std::mutex m_mutex;
+#endif
std::unordered_map<std::string, Algo_Info> m_algo_info;
};