mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[Threading][Windows] Don't include <windows.h>
We can't safely include <windows.h> because it defines a large number of macros, some of which clash with things in the Swift source tree, and others of which clash with things in the LLVM source tree. Sadly we *also* can't just include the Windows headers we need, because they pull in some of the problematic macros. In this instance, the best thing seems to be to grab the definitions for the types and functions we are going to use and put them in their own header file. If we define them correctly, then #including <windows.h> before or after this header won't have any adverse effects. rdar://90776105
This commit is contained in:
@@ -17,13 +17,7 @@
|
||||
#ifndef SWIFT_THREADING_IMPL_WIN32_H
|
||||
#define SWIFT_THREADING_IMPL_WIN32_H
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define NOMINMAX
|
||||
#include <windows.h>
|
||||
|
||||
// <windows.h> defines some unhelpful macros
|
||||
#undef Yield
|
||||
#undef ERROR
|
||||
#include "Win32/Win32Defs.h"
|
||||
|
||||
#include <atomic>
|
||||
|
||||
@@ -32,7 +26,7 @@ namespace threading_impl {
|
||||
|
||||
// .. Thread related things ..................................................
|
||||
|
||||
using thread_id = DWORD;
|
||||
using thread_id = ::DWORD;
|
||||
|
||||
inline thread_id thread_get_current() { return ::GetCurrentThreadId(); }
|
||||
thread_id thread_get_main();
|
||||
@@ -41,7 +35,7 @@ inline bool threads_same(thread_id a, thread_id b) { return a == b; }
|
||||
|
||||
// .. Mutex support ..........................................................
|
||||
|
||||
using mutex_handle = SRWLOCK;
|
||||
using mutex_handle = ::SRWLOCK;
|
||||
|
||||
inline void mutex_init(mutex_handle &handle, bool checked=false) {
|
||||
handle = SRWLOCK_INIT;
|
||||
@@ -49,23 +43,23 @@ inline void mutex_init(mutex_handle &handle, bool checked=false) {
|
||||
inline void mutex_destroy(mutex_handle &handle) { }
|
||||
|
||||
inline void mutex_lock(mutex_handle &handle) {
|
||||
AcquireSRWLockExclusive(&handle);
|
||||
::AcquireSRWLockExclusive(&handle);
|
||||
}
|
||||
inline void mutex_unlock(mutex_handle &handle) {
|
||||
ReleaseSRWLockExclusive(&handle);
|
||||
::ReleaseSRWLockExclusive(&handle);
|
||||
}
|
||||
inline bool mutex_try_lock(mutex_handle &handle) {
|
||||
return !!TryAcquireSRWLockExclusive(&handle);
|
||||
return !!::TryAcquireSRWLockExclusive(&handle);
|
||||
}
|
||||
|
||||
inline void mutex_unsafe_lock(mutex_handle &handle) {
|
||||
AcquireSRWLockExclusive(&handle);
|
||||
::AcquireSRWLockExclusive(&handle);
|
||||
}
|
||||
inline void mutex_unsafe_unlock(mutex_handle &handle) {
|
||||
ReleaseSRWLockExclusive(&handle);
|
||||
::ReleaseSRWLockExclusive(&handle);
|
||||
}
|
||||
|
||||
using lazy_mutex_handle = SRWLOCK;
|
||||
using lazy_mutex_handle = ::SRWLOCK;
|
||||
|
||||
// We don't need to be lazy here because Win32 has SRWLOCK_INIT.
|
||||
inline constexpr lazy_mutex_handle lazy_mutex_initializer() {
|
||||
@@ -74,20 +68,20 @@ inline constexpr lazy_mutex_handle lazy_mutex_initializer() {
|
||||
inline void lazy_mutex_destroy(lazy_mutex_handle &handle) { }
|
||||
|
||||
inline void lazy_mutex_lock(lazy_mutex_handle &handle) {
|
||||
AcquireSRWLockExclusive(&handle);
|
||||
::AcquireSRWLockExclusive(&handle);
|
||||
}
|
||||
inline void lazy_mutex_unlock(lazy_mutex_handle &handle) {
|
||||
ReleaseSRWLockExclusive(&handle);
|
||||
::ReleaseSRWLockExclusive(&handle);
|
||||
}
|
||||
inline bool lazy_mutex_try_lock(lazy_mutex_handle &handle) {
|
||||
return !!TryAcquireSRWLockExclusive(&handle);
|
||||
return !!::TryAcquireSRWLockExclusive(&handle);
|
||||
}
|
||||
|
||||
inline void lazy_mutex_unsafe_lock(lazy_mutex_handle &handle) {
|
||||
AcquireSRWLockExclusive(&handle);
|
||||
::AcquireSRWLockExclusive(&handle);
|
||||
}
|
||||
inline void lazy_mutex_unsafe_unlock(lazy_mutex_handle &handle) {
|
||||
ReleaseSRWLockExclusive(&handle);
|
||||
::ReleaseSRWLockExclusive(&handle);
|
||||
}
|
||||
|
||||
// .. Once ...................................................................
|
||||
@@ -116,20 +110,20 @@ inline void once_impl(once_t &predicate, void (*fn)(void *), void *context) {
|
||||
|
||||
#define SWIFT_TLS_DECLARE_DTOR(name) void NTAPI name(void *)
|
||||
|
||||
using tls_key = DWORD;
|
||||
using tls_dtor = PFLS_CALLBACK_FUNCTION;
|
||||
using tls_key = ::DWORD;
|
||||
using tls_dtor = ::PFLS_CALLBACK_FUNCTION;
|
||||
|
||||
inline bool tls_alloc(tls_key &key, tls_dtor dtor) {
|
||||
key = FlsAlloc(dtor);
|
||||
key = ::FlsAlloc(dtor);
|
||||
return key != FLS_OUT_OF_INDEXES;
|
||||
}
|
||||
|
||||
inline void *tls_get(tls_key key) {
|
||||
return FlsGetValue(key);
|
||||
return ::FlsGetValue(key);
|
||||
}
|
||||
|
||||
inline void tls_set(tls_key key, void *value) {
|
||||
FlsSetValue(key, value);
|
||||
::FlsSetValue(key, value);
|
||||
}
|
||||
|
||||
} // namespace threading_impl
|
||||
|
||||
71
include/swift/Threading/Impl/Win32/Win32Defs.h
Normal file
71
include/swift/Threading/Impl/Win32/Win32Defs.h
Normal file
@@ -0,0 +1,71 @@
|
||||
//==--- Win32Defs.h - Windows API definitions ------------------ -*-C++ -*-===//
|
||||
//
|
||||
// This source file is part of the Swift.org open source project
|
||||
//
|
||||
// Copyright (c) 2022 Apple Inc. and the Swift project authors
|
||||
// Licensed under Apache License v2.0 with Runtime Library Exception
|
||||
//
|
||||
// See https://swift.org/LICENSE.txt for license information
|
||||
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// We cannot include <windows.h> from the Threading headers because they get
|
||||
// included all over the place and <windows.h> defines a large number of
|
||||
// obnoxious macros. Instead, this header declares *just* what we need.
|
||||
//
|
||||
// If you need <windows.h> in a file, please make sure to include it *before*
|
||||
// this file, or you'll get errors about RTL_SRWLOCK.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef SWIFT_THREADING_IMPL_WIN32_DEFS_H
|
||||
#define SWIFT_THREADING_IMPL_WIN32_DEFS_H
|
||||
|
||||
#define DECLSPEC_IMPORT __declspec(dllimport)
|
||||
#define WINBASEAPI DECLSPEC_IMPORT
|
||||
#define WINAPI __stdcall
|
||||
#define NTAPI __stdcall
|
||||
|
||||
// <windows.h> #defines VOID rather than typedefing it(!) Changing that
|
||||
// to use a typedef instead isn't problematic later on, so let's do that.
|
||||
#undef VOID
|
||||
|
||||
typedef void VOID, *PVOID;
|
||||
typedef unsigned char BYTE;
|
||||
typedef BYTE BOOLEAN;
|
||||
typedef int BOOL;
|
||||
typedef unsigned long DWORD;
|
||||
|
||||
typedef VOID (NTAPI* PFLS_CALLBACK_FUNCTION)(PVOID lpFlsData);
|
||||
|
||||
// We can't define this struct if <winnt.h> already did so
|
||||
#ifndef _WINNT_
|
||||
struct _RTL_SRWLOCK {
|
||||
PVOID Ptr;
|
||||
};
|
||||
#endif // _WINNT_
|
||||
|
||||
typedef struct _RTL_SRWLOCK RTL_SRWLOCK, *PRTL_SRWLOCK;
|
||||
typedef RTL_SRWLOCK SRWLOCK, *PSRWLOCK;
|
||||
|
||||
// These have to be #defines, to avoid problems with <windows.h>
|
||||
#define RTL_SRWLOCK_INIT {0}
|
||||
#define SRWLOCK_INIT RTL_SRWLOCK_INIT
|
||||
#define FLS_OUT_OF_INDEXES ((DWORD)0xFFFFFFFF)
|
||||
|
||||
extern "C" {
|
||||
WINBASEAPI DWORD WINAPI GetCurrentThreadId(VOID);
|
||||
|
||||
WINBASEAPI VOID WINAPI InitializeSRWLock(PSRWLOCK SRWLock);
|
||||
WINBASEAPI VOID WINAPI ReleaseSRWLockExclusive(PSRWLOCK SRWLock);
|
||||
WINBASEAPI VOID WINAPI AcquireSRWLockExclusive(PSRWLOCK SRWLock);
|
||||
WINBASEAPI BOOLEAN WINAPI TryAcquireSRWLockExclusive(PSRWLOCK SRWLock);
|
||||
|
||||
WINBASEAPI DWORD WINAPI FlsAlloc(PFLS_CALLBACK_FUNCTION lpCallback);
|
||||
WINBASEAPI PVOID WINAPI FlsGetValue(DWORD dwFlsIndex);
|
||||
WINBASEAPI BOOL WINAPI FlsSetValue(DWORD dwFlsIndex, PVOID lpFlsData);
|
||||
WINBASEAPI BOOL WINAPI FlsFree(DWORD dwFlsIndex);
|
||||
}
|
||||
|
||||
#endif // SWIFT_THREADING_IMPL_WIN32_DEFS_H
|
||||
Reference in New Issue
Block a user