Skip to content

Commit 334e6c3

Browse files
committed
Enable runOnBackgroundThread for spawn() on Windows
1 parent 4255e66 commit 334e6c3

File tree

4 files changed

+115
-168
lines changed

4 files changed

+115
-168
lines changed

Sources/Subprocess/Configuration.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -660,7 +660,11 @@ internal struct IODescriptor: ~Copyable {
660660
#endif
661661

662662
internal var closeWhenDone: Bool
663+
#if canImport(WinSDK)
664+
internal nonisolated(unsafe) let descriptor: Descriptor
665+
#else
663666
internal let descriptor: Descriptor
667+
#endif
664668

665669
internal init(
666670
_ descriptor: Descriptor,

Sources/Subprocess/IO/AsyncIO+Windows.swift

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -86,50 +86,12 @@ final class AsyncIO: @unchecked Sendable {
8686
}
8787
}
8888

89-
// Monitor loop
90-
while true {
91-
var bytesTransferred: DWORD = 0
92-
var targetFileDescriptor: UInt64 = 0
93-
var overlapped: LPOVERLAPPED? = nil
9489
// Monitor loop
9590
while true {
9691
var bytesTransferred: DWORD = 0
9792
var targetFileDescriptor: UInt64 = 0
9893
var overlapped: LPOVERLAPPED? = nil
9994

100-
let monitorResult = GetQueuedCompletionStatus(
101-
context.ioCompletionPort,
102-
&bytesTransferred,
103-
&targetFileDescriptor,
104-
&overlapped,
105-
INFINITE
106-
)
107-
if !monitorResult {
108-
let lastError = GetLastError()
109-
if lastError == ERROR_BROKEN_PIPE {
110-
// We finished reading the handle. Signal EOF by
111-
// finishing the stream.
112-
// NOTE: here we deliberately leave now unused continuation
113-
// in the store. Windows does not offer an API to remove a
114-
// HANDLE from an IOCP port, therefore we leave the registration
115-
// to signify the HANDLE has already been resisted.
116-
let continuation = _registration.withLock { store -> SignalStream.Continuation? in
117-
if let continuation = store[targetFileDescriptor] {
118-
return continuation
119-
}
120-
return nil
121-
}
122-
continuation?.finish()
123-
continue
124-
} else {
125-
let error = SubprocessError(
126-
code: .init(.asyncIOFailed("GetQueuedCompletionStatus failed")),
127-
underlyingError: .init(rawValue: lastError)
128-
)
129-
reportError(error)
130-
break
131-
}
132-
}
13395
let monitorResult = GetQueuedCompletionStatus(
13496
context.ioCompletionPort,
13597
&bytesTransferred,

Sources/Subprocess/Platforms/Subprocess+Unix.swift

Lines changed: 0 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -674,51 +674,6 @@ extension PlatformOptions: CustomStringConvertible, CustomDebugStringConvertible
674674
return self.description(withIndent: 0)
675675
}
676676
}
677-
678-
// Special keys used in Error's user dictionary
679-
extension String {
680-
static let debugDescriptionErrorKey = "DebugDescription"
681-
}
682-
683-
internal func pthread_create(_ body: @Sendable @escaping () -> ()) throws(SubprocessError.UnderlyingError) -> pthread_t {
684-
final class Context {
685-
let body: @Sendable () -> ()
686-
init(body: @Sendable @escaping () -> Void) {
687-
self.body = body
688-
}
689-
}
690-
#if canImport(Glibc) || canImport(Musl)
691-
func proc(_ context: UnsafeMutableRawPointer?) -> UnsafeMutableRawPointer? {
692-
(Unmanaged<AnyObject>.fromOpaque(context!).takeRetainedValue() as! Context).body()
693-
return nil
694-
}
695-
#elseif canImport(Bionic)
696-
func proc(_ context: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer {
697-
(Unmanaged<AnyObject>.fromOpaque(context).takeRetainedValue() as! Context).body()
698-
return context
699-
}
700-
#endif
701-
#if (os(Linux) && canImport(Glibc)) || canImport(Bionic)
702-
var thread = pthread_t()
703-
#else
704-
var thread: pthread_t?
705-
#endif
706-
let rc = pthread_create(
707-
&thread,
708-
nil,
709-
proc,
710-
Unmanaged.passRetained(Context(body: body)).toOpaque()
711-
)
712-
if rc != 0 {
713-
throw SubprocessError.UnderlyingError(rawValue: rc)
714-
}
715-
#if (os(Linux) && canImport(Glibc)) || canImport(Bionic)
716-
return thread
717-
#else
718-
return thread!
719-
#endif
720-
}
721-
722677
#endif // !canImport(Darwin)
723678

724679
extension ProcessIdentifier {

0 commit comments

Comments
 (0)