Reference the following web page, on which Microsoft states that it is un-thread-safe to invoke any CRT functions inside of static initializers, and that doing so can lead to deadlocks in multi-threaded applications when such initializers are invoked during a DllMain(): http://msdn.microsoft.com/en-us/library/ms682583%28v=vs.85%29.aspx
Poco's Crypto module contains a static instance of the OpenSSLInitializer class. Therefore, the constructor of this static instance is run during a DllMain(). That constructor, on at least one occasion runs code that includes invoking a CRT function and can thus create this deadlock situation. The specific occasion I have observed is:
OpenSSLInitializer::OpenSSLInitializer() -> OpenSSLInitializer::initialize() -> OPENSSL_config() -> CONF_modules_load_file() -> CONF_get1_default_config_file() -> getenv()
getenv() is a CRT function and on Windows, it includes blocking on acquiring the _ENV_LOCK lock. When getenv() is run in a DllMain() context, the running thread of course already has the library load lock at this point. But in my application, there are times when some other thread concurrently already has the _ENV_LOCK and needs to load a library to complete its task, thus needing to acquire the library load lock. Thus, the deadlock. And again, this is the exact type of thing Microsoft warns about on that web page where they say that static initialization code should not be doing anything that will invoke CRT functions.
For all I know, there might be many more such violations over the course of the OpenSSLInitializer constructor. I haven't really looked. This getenv() is the one causing my current deadlock, though.