-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Simple portions of the Windows Port #1796
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@swift-ci please test |
CC: @parkera @millenomi |
hahaha, |
d0ab4a9
to
0ee5a7a
Compare
@swift-ci please test |
@swift-ci please test Linux platform |
@@ -307,29 +304,21 @@ CF_EXPORT int _NS_access(const char *name, int amode); | |||
#define WIN32_LEAN_AND_MEAN | |||
|
|||
#ifndef WINVER | |||
#define WINVER 0x0501 | |||
#define WINVER 0x0601 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
@@ -351,7 +351,7 @@ CFBurstTrieRef CFBurstTrieCreateFromFile(CFStringRef path) { | |||
if (stat(filename, &sb) != 0) return NULL; | |||
|
|||
/* Check if file can be opened */ | |||
if ((fd=open(filename, CF_OPENFLGS|O_RDONLY)) < 0) return NULL; | |||
if ((fd = open(filename, CF_OPENFLGS|O_RDONLY, 0)) < 0) return NULL; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs to use _wsopen_s
on Windows, not open
.
Unfortunately, the story with C APIs is the same as with the *A vs *W variants of Win32 functions -- you must use the wide-character variants for Unicode to work at all.
Please go through and audit any C API calls through SCF and make sure that the _w variants are used on Windows. It's probably a good idea to separate all C APIs which take strings into an abstraction layer somewhere.
I'd do something like this. Have an abstraction layer which provides both UTF-8 and UTF-16 variants of each C API that we use:
int scf_open(const char *);
int scf_wopen(const uint16_t *, size_t len); // do NOT use wchar_t, it's different size on different platforms
int scf_cfopen(CFStringRef);
In the implementations (pseudocode):
int scf_open(const char *s) {
if (windows) {
// We have a UTF-8 string and are on Windows, convert to UTF-16
auto x = convert_to_utf16(s);
return scf_wopen(x.ptr, x.length);
} else {
// We have a UTF-8 string and are on UNIX, no conversion needed
return ::open(s);
}
}
int scf_wopen(const uint16_t *s, size_t len) {
if (windows) {
// We have a UTF-16 string and are on Windows, no conversion needed
return ::_wsopen_s(s);
} else {
// We have a UTF-16 string and are on UNIX, convert to UTF-8
return scf_open(convert_to_utf8(s));
}
}
int scf_cfopen(CFStringRef s) {
if (windows) {
return scf_wopen(CFStringGetCharactersPtr(s), CFStringGetLength(s));
} else {
char filename[PATH_MAX];
CFStringGetCString(s, filename, PATH_MAX, kCFStringEncodingUTF8);
return scf_open(filename);
}
}
That way you can call either the UTF-8 or UTF-16 variant depending on what kind of string you have coming from the input, and it'll do the right thing on each platform in order to minimize conversions.
For example, when you have a CFString and need to pass it to a native Win32 API, you can actually avoid the UTF-8 conversion you're doing here (which again is currently broken due to UTF-8 not being supported).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
open
is not open
, it is a macro, and replaces it with _NS_open
, and it does go through _wopen_s
. I believe that all of the ones have already been replaced with _NS_*
equivalents.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, didn't notice that. However, the approach I suggested would still be more performant on Windows because you're not converting (in many cases) from UTF-16 to UTF-8 right back to UTF-16 again. Having two roundtrips like that every time a Win32 API is called is going to add up.
But performance improvements like that can be done in a later change, so I rescind my "changes requested" for now. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I agree, that would be a great follow up!
code is correct, suggested perf improvements can be done in a later patch
C does not support default valued arguments. Remove the default valued argument and update the invocations.
Not all deployment targets use POSIX threads (pthreads). Use the POSIX mandated macro `_POSIX_THREADS` to detect whether POSIX threads are in use. Conditionally include `unistd.h` which is the Unix standard header which provides the definition for `_POSIX_THREADS` if the platform uses POSIX threads. Unfortunately, clang does not define `__unix__` for macOS (Bob Wilson does not recall why this was the case, and we have yet to test if we can get away with defining `__unix__` for the platform without breaking existing software).
We need to forward declare the struct as otherwise the definition is local to the declaration and cannot be defined. This addresses the `-Wvisibility` warning when building for Windows.
Use `<sys/param.h>` for the definition of min/max on Linux. This header is also available on FreeBSD. On Windows, we inherit the definition from `generic_win_base.h` from libdispatch.
For compatibility, define a mode_t which is an integral type. This matches the code in libdispatch as well as matches the type definition on Linux.
fts.h is a BSD4.4 conforming header. Linux (via glibc) and Haiku also provide it. Unfortunately, there is no easy check for this header. It is not present on AIX, HP-UX, IRIX, OSX/1, Solaris, and BeOS. The current guard at least allows us to build for Windows.
`dirent.h` is part of SuS, so it should be available on pretty much any Unix. Guard the inclusion for Windows.
Rather than trying to define `scalbn` in terms of `scalb`, use the MSVC provided definition.
Although `major` and `minor` are not part of POSIX or SuS, treat them as part of SuS as many Unixes provide the interfaces. `dirent` is part of the SuS and can be safely guarded by this check.
Guard the os_unfair_lock definition to pthread to when POSIX threads are present. The single use of `os_unfair_lock` will be resolved later with the use of `SRWLOCK` on Windows.
rdar://problem/7923891 is no longer relevant as we are building against a modern libdispatch when targeting windows. Remove the conflicting macro definition which breaks CoreFoundation.
Replicate the QoS groups for Windows based on the Linux behaviour
`bzero` is deprecated, use `memset` as suggested by the specification. This avoids a warning for the inclusion of `strings.h`.
The Apple System Logger is not available on Windows (as it is not open source). Do not include `asl.h` on Windows.
Use the system provided definition through `time.h` instead. This has been provided for a long time now.
`unistd.h` is the unix standard header. This header cannot be included on all systems. It should normally be guarded by `__unix__`. However, macOS X does not define `__unix__` for some reason, so add an additional condition for the inclusion.
Win32 uses WinSock2 rather than the BSD sockets API. Guard the inclusion accordingly.
The use of the signed value here would result in a tautological comparison which was always out of range. Use the unsigned type instead.
Windows has a macro `_environ` which provides access through the environment accessor function `__environ_p`.
The function `_CFLocaleCopyLocaleIdentifierByAddingLikelySubtags` is used internally. Ensure that we provide the definition of the function.
The FLS APIs provide additional flexibility and give similar semantics as pthread TLS.
`sys/mman.h` is a POSIX header. Windows is a non-POSIX environment. Guard the inclusion accordingly.
The local definition must match the signature from msvcrt otherwise there are type mismatch errors. Just rename it to `_CF_isspace` and change the signature to be more ergonomic.
The macro needs to be defined for the Windows port. Duplicate the definition from the Linux path.
We wish to use the constant CFStrings when targeting Windows as well.
We will consider the list last. There is no mention of `langs` anywhere. Assume that this is left over from previous builds.
This was not defined, and would break the build for Windows.
Reorder the definitions to ensure that the symbol is defined before the use.
Load the timezone information from the registry on Windows. Add missing definition and define structures for Windows as well.
…ifiers` Add a cast for the discarded qualifier.
Clean up a formatting warning.
Declare the function for the Windows port.
Add a local definition of `timeradd` for Windows.
Windows uses `signed char` rather than `unsigned char`. Add a cast to silence the `-Wpointer-sign` warning.
Update the signatures for the timer functions to match the current declarations.
Ensure that the local macro definitions are defined early enough for the forward declarations to be provided for the use.
If `dispatch/private.h` is not available, then we fall back to forward declaring dispatch interfaces. One of those is the `mach_port_t` shim typedef.
Include `process.h` for the declaration of the threading functions.
This header is used pervasively, and we use certain types defined from this umbrella header.
Do not attempt to define the core COM types on Windows. These conflict with the system provided definitions which are included via ForSwiftFoundationOnly.h.
67c5b56
to
b145058
Compare
@swift-ci please test |
I think that I can improve some of the Windows implementations, but, lets get the basic bits in and do that in a follow up. |
This is set of changes that are simple and non-controversial for the Windows port. This allows us to work on a smaller set of changes that have more interesting consequences (like threading and locking) without having to worry about the additional context of these patches. It also makes it easier to work on the port as it reduces the likelihood of conflicts.