diff options
author | Matej Kenda <[email protected]> | 2015-11-02 14:39:40 +0100 |
---|---|---|
committer | Matej Kenda <[email protected]> | 2015-11-03 08:26:54 +0100 |
commit | 1ec38dc7e6de206c0da6f8e0bd1605cc022a1a0c (patch) | |
tree | adab66ddb5b8e49e15d6a140002e8f86808935f1 /src/lib/base | |
parent | 50878a88d285344949f3257a4a9fa0137af2b5a2 (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.h | 54 |
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; }; |