diff options
author | Jack Lloyd <[email protected]> | 2015-12-04 09:27:10 -0500 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2015-12-04 09:27:10 -0500 |
commit | 760c8434227be7cea3ac315b3d5610e959af600e (patch) | |
tree | f93d13d28b07d046027cc2e61c0e64b641076b84 /src | |
parent | 6ffc6d4da50bc23e0d5ba039fe1e18825513a5f2 (diff) | |
parent | 12bd679149183d59927c433eb95fbc4f68cfd4b3 (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')
-rw-r--r-- | src/lib/base/algo_registry.h | 60 |
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; }; |