提交 fcb318c6 编写于 作者: M Matt Caswell

Fix Windows 64 bit crashes

The function InitOnceExceuteOnce is the best way to support the
implementation of CRYPTO_THREAD_run_once() on Windows. Unfortunately
WinXP doesn't have it. To get around that we had two different
implementations: one for WinXP and one for later versions. Which one was
used was based on the value of _WIN32_WINNT.

This approach was starting to cause problems though because other parts of
OpenSSL assume _WIN32_WINNT is going to be 0x0501 and crashes were
occurring dependant on include file ordering. In addition a conditional
based on _WIN32_WINNT had made its way into a public header file through
commit 5c4328f0. This is problematic because the value of this macro can
vary between OpenSSL build time and application build time.

The simplest solution to this mess is just to always use the WinXP version
of CRYPTO_THREAD_run_once(). Its perhaps slightly sub-optimal but probably
not noticably.

GitHub Issue #1086
Reviewed-by: NRichard Levitte <levitte@openssl.org>
上级 739a1eb1
......@@ -55,12 +55,14 @@ void CRYPTO_THREAD_lock_free(CRYPTO_RWLOCK *lock)
return;
}
# if _WIN32_WINNT < 0x0600
# define ONCE_UNINITED 0
# define ONCE_ININIT 1
# define ONCE_DONE 2
/*
* We don't use InitOnceExecuteOnce because that isn't available in WinXP which
* we still have to support.
*/
int CRYPTO_THREAD_run_once(CRYPTO_ONCE *once, void (*init)(void))
{
LONG volatile *lock = (LONG *)once;
......@@ -81,27 +83,6 @@ int CRYPTO_THREAD_run_once(CRYPTO_ONCE *once, void (*init)(void))
return (*lock == ONCE_DONE);
}
# else
BOOL CALLBACK once_cb(PINIT_ONCE once, PVOID p, PVOID *pp)
{
void (*init)(void) = p;
init();
return TRUE;
}
int CRYPTO_THREAD_run_once(CRYPTO_ONCE *once, void (*init)(void))
{
if (InitOnceExecuteOnce(once, once_cb, init, NULL))
return 1;
return 0;
}
# endif
int CRYPTO_THREAD_init_local(CRYPTO_THREAD_LOCAL *key, void (*cleanup)(void *))
{
*key = TlsAlloc();
......
......@@ -396,13 +396,8 @@ typedef unsigned int CRYPTO_THREAD_ID;
typedef DWORD CRYPTO_THREAD_LOCAL;
typedef DWORD CRYPTO_THREAD_ID;
# if _WIN32_WINNT < 0x0600
typedef LONG CRYPTO_ONCE;
# define CRYPTO_ONCE_STATIC_INIT 0
# else
typedef INIT_ONCE CRYPTO_ONCE;
# define CRYPTO_ONCE_STATIC_INIT INIT_ONCE_STATIC_INIT
# endif
# define CRYPTO_ONCE_STATIC_INIT 0
# else
# include <pthread.h>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册