@@ -128,9 +128,16 @@ final class StandardIO: ManagedProcess.IO & Sendable {
128
128
// `buf` isn't used concurrently.
129
129
nonisolated ( unsafe) let buf = UnsafeMutableBufferPointer< UInt8> . allocate( capacity: Int ( getpagesize ( ) ) )
130
130
131
+ var didCleanup = false
132
+ let cleanupRelay : ( ) -> Void = {
133
+ if didCleanup { return }
134
+ didCleanup = true
135
+ self . cleanupRelay ( readFd: readFromFd, writeFd: writeToFd, buffer: buf, log: self . log)
136
+ }
137
+
131
138
try ProcessSupervisor . default. poller. add ( readFromFd, mask: EPOLLIN) { mask in
132
139
if mask. isHangup && !mask. readyToRead {
133
- self . cleanupRelay ( readFd : readFromFd , writeFd : writeToFd , buffer : buf , log : self . log )
140
+ cleanupRelay ( )
134
141
return
135
142
}
136
143
// Loop so that in the case that someone wrote > buf.count down the pipe
@@ -146,7 +153,7 @@ final class StandardIO: ManagedProcess.IO & Sendable {
146
153
let w = writeTo. write ( view)
147
154
if w. wrote != r. read {
148
155
self . log? . error ( " stopping relay: short write for stdio " )
149
- self . cleanupRelay ( readFd : readFromFd , writeFd : writeToFd , buffer : buf , log : self . log )
156
+ cleanupRelay ( )
150
157
return
151
158
}
152
159
}
@@ -156,13 +163,13 @@ final class StandardIO: ManagedProcess.IO & Sendable {
156
163
self . log? . error ( " failed with errno \( errno) while reading for fd \( readFromFd) " )
157
164
fallthrough
158
165
case . eof:
159
- self . cleanupRelay ( readFd : readFromFd , writeFd : writeToFd , buffer : buf , log : self . log )
166
+ cleanupRelay ( )
160
167
self . log? . debug ( " closing relay for \( readFromFd) " )
161
168
return
162
169
case . again:
163
170
// We read all we could, exit.
164
171
if mask. isHangup {
165
- self . cleanupRelay ( readFd : readFromFd , writeFd : writeToFd , buffer : buf , log : self . log )
172
+ cleanupRelay ( )
166
173
}
167
174
return
168
175
default :
0 commit comments