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 | |
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
-rw-r--r-- | doc/credits.rst | 5 | ||||
-rw-r--r-- | doc/license.txt | 1 | ||||
-rw-r--r-- | src/lib/base/algo_registry.h | 60 |
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 + E: [email protected] + 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; }; |