aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/credits.rst5
-rw-r--r--doc/license.txt1
-rw-r--r--src/lib/base/algo_registry.h60
3 files changed, 60 insertions, 6 deletions
diff --git a/doc/credits.rst b/doc/credits.rst
index 8a18d2237..6d62b6380 100644
--- a/doc/credits.rst
+++ b/doc/credits.rst
@@ -55,6 +55,11 @@ snail-mail address (S), and Bitcoin address (B).
D: LZMA compression module
S: Czech Republic
+ N: Matej Kenda
+ D: Locking in Algo_Registry for Windows OS
+ S: Slovenia
+
N: Adam Langley
D: Curve25519
diff --git a/doc/license.txt b/doc/license.txt
index 4e3907f48..2eb91b622 100644
--- a/doc/license.txt
+++ b/doc/license.txt
@@ -24,6 +24,7 @@ Copyright (C) 1999-2013,2014,2015 Jack Lloyd
2014 Andrew Moon
2015 Daniel Seither (Kullo GmbH)
2015 Simon Warta (Kullo GmbH)
+ 2015 Matej Kenda (TopIT d.o.o.)
All rights reserved.
Redistribution and use in source and binary forms, with or without
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;
};