I think this is a subtle point that only becomes evident after spending a lot of time working with or trying to build a cross-platform framework. If you commit to zero platform-specific API, clients wind up reverse-engineering your abstractions in order to integrate with their target platform(s), which makes it much harder to evolve your framework.
Where is this thread ID coming from? As far as I’m aware, Win32 processes do not have a “main” thread. Just like POSIX platforms, a Win32 process can exit the thread that WinMain() was called on. Is this a Swift- or Foundation-provided construct?
Edit: I see this is coming from the PROCESS_INFORMATION returned by CreateProcess. Since you are required to close the thread handle, that means the handle will still be valid even if the process exits the thread. You just won’t be able to do much with it if it does. Is Foundation taking care to call CloseHandle() on the thread?