Skip to content

Commit a865736

Browse files
authored
Avoid assertion for legitimate case where reply received for handler that was closed (#1437)
Avoid assertion for legitimate case where reply received for handler that was closed
1 parent b450670 commit a865736

1 file changed

Lines changed: 15 additions & 9 deletions

File tree

Sources/SwiftBuild/SWBBuildServiceConnection.swift

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,12 @@ typealias swb_build_service_connection_message_handler_t = @Sendable (UInt64, SW
5757

5858
/// Track whether the channels have been cleared because the service has crashed.
5959
var channelsHaveBeenCleared = false
60+
61+
/// A nil handler for a known channel is expected, service crash or client closed the channel before the reply arrived.
62+
/// A nil handler for an unknown channel is unexpected.
63+
func isChannelKnown(_ channel: UInt64) -> Bool {
64+
return channel <= nextChannelID
65+
}
6066
}
6167

6268
/// An "unfair lock" that protects the channels state. Should be held only for very short periods of time.
@@ -303,14 +309,6 @@ typealias swb_build_service_connection_message_handler_t = @Sendable (UInt64, SW
303309
let channel = headerFrame.channel
304310
let msgSize = Int(headerFrame.messageSize)
305311

306-
// Look up the channel by its number.
307-
let handler = self.channelState.withLock({ $0.channels[channel] })
308-
if handler == nil {
309-
// It’s an error if we didn’t find a channel here.
310-
// FIXME: We need to handle this error in a better way.
311-
assertionFailure("no handler for channel: \(channel)")
312-
}
313-
314312
// If we don’t have all the data yet, we can go no further.
315313
if offset + msgSize > data.count {
316314
// Move the offset back to just before the header, so we’ll see it again next time around.
@@ -320,7 +318,15 @@ typealias swb_build_service_connection_message_handler_t = @Sendable (UInt64, SW
320318
}
321319

322320
// Otherwise, look up the channel by its number.
323-
handler?(channel, data.subdata(in: offset..<(offset + msgSize)))
321+
let (handler, isChannelKnown) = self.channelState.withLock {
322+
return ($0.channels[channel], $0.isChannelKnown(channel))
323+
}
324+
325+
if let handler {
326+
handler(channel, data.subdata(in: offset..<(offset + msgSize)))
327+
} else {
328+
assert(isChannelKnown, "Received reply for unknown channel: \(channel)")
329+
}
324330

325331
// Move on to the next message.
326332
offset += msgSize

0 commit comments

Comments
 (0)