Fix data <-> function pointer casts in thread_win.c.
The uses of |memcpy| to cast pointer-to-function to pointer-to-data and back again did not have well-defined semantics. Use a union instead to avoid the need for such a conversion get well-defined semantics. Change-Id: I8ee54a83ba75440f7bc78c194eb55e2cf09b05d8 Reviewed-on: https://boringssl-review.googlesource.com/6972 Reviewed-by: David Benjamin <davidben@google.com>
This commit is contained in:
parent
f5f4be8fac
commit
9333d6df11
@ -31,7 +31,13 @@
|
|||||||
OPENSSL_COMPILE_ASSERT(sizeof(CRYPTO_MUTEX) >= sizeof(CRITICAL_SECTION),
|
OPENSSL_COMPILE_ASSERT(sizeof(CRYPTO_MUTEX) >= sizeof(CRITICAL_SECTION),
|
||||||
CRYPTO_MUTEX_too_small);
|
CRYPTO_MUTEX_too_small);
|
||||||
|
|
||||||
static void run_once(CRYPTO_once_t *once, void (*init)(void *), void *arg) {
|
union run_once_arg_t {
|
||||||
|
void (*func)(void);
|
||||||
|
void *data;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void run_once(CRYPTO_once_t *once, void (*init)(union run_once_arg_t),
|
||||||
|
union run_once_arg_t arg) {
|
||||||
/* Values must be aligned. */
|
/* Values must be aligned. */
|
||||||
assert((((uintptr_t) once) & 3) == 0);
|
assert((((uintptr_t) once) & 3) == 0);
|
||||||
|
|
||||||
@ -72,17 +78,13 @@ static void run_once(CRYPTO_once_t *once, void (*init)(void *), void *arg) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void call_once_init(void *arg) {
|
static void call_once_init(union run_once_arg_t arg) {
|
||||||
void (*init_func)(void);
|
arg.func();
|
||||||
/* MSVC does not like casting between data and function pointers. */
|
|
||||||
memcpy(&init_func, &arg, sizeof(void *));
|
|
||||||
init_func();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRYPTO_once(CRYPTO_once_t *in_once, void (*init)(void)) {
|
void CRYPTO_once(CRYPTO_once_t *in_once, void (*init)(void)) {
|
||||||
void *arg;
|
union run_once_arg_t arg;
|
||||||
/* MSVC does not like casting between data and function pointers. */
|
arg.func = init;
|
||||||
memcpy(&arg, &init, sizeof(void *));
|
|
||||||
run_once(in_once, call_once_init, arg);
|
run_once(in_once, call_once_init, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,16 +111,18 @@ void CRYPTO_MUTEX_cleanup(CRYPTO_MUTEX *lock) {
|
|||||||
DeleteCriticalSection((CRITICAL_SECTION *) lock);
|
DeleteCriticalSection((CRITICAL_SECTION *) lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void static_lock_init(void *arg) {
|
static void static_lock_init(union run_once_arg_t arg) {
|
||||||
struct CRYPTO_STATIC_MUTEX *lock = arg;
|
struct CRYPTO_STATIC_MUTEX *lock = arg.data;
|
||||||
if (!InitializeCriticalSectionAndSpinCount(&lock->lock, 0x400)) {
|
if (!InitializeCriticalSectionAndSpinCount(&lock->lock, 0x400)) {
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRYPTO_STATIC_MUTEX_lock_read(struct CRYPTO_STATIC_MUTEX *lock) {
|
void CRYPTO_STATIC_MUTEX_lock_read(struct CRYPTO_STATIC_MUTEX *lock) {
|
||||||
|
union run_once_arg_t arg;
|
||||||
|
arg.data = lock;
|
||||||
/* Since we have to support Windows XP, read locks are actually exclusive. */
|
/* Since we have to support Windows XP, read locks are actually exclusive. */
|
||||||
run_once(&lock->once, static_lock_init, lock);
|
run_once(&lock->once, static_lock_init, arg);
|
||||||
EnterCriticalSection(&lock->lock);
|
EnterCriticalSection(&lock->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user