Skip to content

Commit b11e683

Browse files
authored
Monitor process termination with kqueue instead of DispatchSource (#290)
On FreeBSD, Subprocess spawns children with pdfork(2). Per the man page such a child will not cause SIGCHLD on termination, which means DispatchSource does not work with processes spawned via pdfork. Replace the DispatchSource implementation with a kqueue-based monitor shared by all kqueue platforms, mirroring the Linux epoll/pidfd backend. This change also allows us to completely remove the use of Dispatch from Subprocess.
1 parent e163c1b commit b11e683

7 files changed

Lines changed: 386 additions & 61 deletions

File tree

Sources/Subprocess/IO/AsyncIO+KQueue.swift

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -38,48 +38,8 @@ private typealias _Mutex = OSAllocatedUnfairLock
3838
private typealias _Mutex = Synchronization.Mutex
3939
#endif
4040

41-
// The kevent() C function and the kevent struct share the same name.
42-
// Swift can disambiguate when given an explicit function type.
43-
private let _kevent:
44-
@convention(c) (
45-
Int32,
46-
UnsafePointer<kevent>?,
47-
Int32,
48-
UnsafeMutablePointer<kevent>?,
49-
Int32,
50-
UnsafePointer<timespec>?
51-
) -> Int32 = kevent
52-
53-
private let _kqueueEventSize = 256
5441
private let _registration: _Mutex<Registration> = _Mutex(Registration())
5542

56-
private func _makeKevent(
57-
ident: UInt,
58-
filter: Int16,
59-
flags: UInt16
60-
) -> kevent {
61-
#if canImport(Darwin)
62-
return kevent(
63-
ident: ident,
64-
filter: filter,
65-
flags: flags,
66-
fflags: 0,
67-
data: 0,
68-
udata: nil
69-
)
70-
#else
71-
return kevent(
72-
ident: ident,
73-
filter: filter,
74-
flags: flags,
75-
fflags: 0,
76-
data: 0,
77-
udata: nil,
78-
ext: (0, 0, 0, 0)
79-
)
80-
#endif
81-
}
82-
8343
final class AsyncIO: Sendable {
8444

8545
typealias OutputStream = AsyncThrowingStream<SubprocessOutputSequence.Buffer, any Error>

0 commit comments

Comments
 (0)