@@ -55,23 +55,24 @@ public actor SandboxService {
5555 private static let sshAuthSocketEnvVar = " SSH_AUTH_SOCK "
5656
5757 class ExitWaiter {
58- public var exitCode : Int32 ? = nil
58+ public var exitStatus : ExitStatus ? = nil
5959 public var continuations : [ CheckedContinuation < ExitStatus , Never > ] = [ ]
6060
61- public func register( _ cc: CheckedContinuation < ExitStatus , Never > ) {
61+ public func wait( _ cc: CheckedContinuation < ExitStatus , Never > ) {
62+ if let exitStatus = exitStatus {
63+ // `doExit` has already been called for this waiter
64+ cc. resume ( returning: exitStatus)
65+ return
66+ }
6267 continuations. append ( cc)
6368 }
6469
65- public func doExit( code : Int32 ) {
70+ public func doExit( exitStatus : ExitStatus ) {
6671 for cc in continuations {
67- cc. resume ( returning: ExitStatus ( exitCode : code ) )
72+ cc. resume ( returning: exitStatus )
6873 }
6974
70- exitCode = code
71- }
72-
73- public func exited( ) -> Bool {
74- exitCode != nil
75+ self . exitStatus = exitStatus
7576 }
7677 }
7778
@@ -620,11 +621,7 @@ public actor SandboxService {
620621 }
621622
622623 let exitStatus = await withCheckedContinuation { cc in
623- // Is this safe since we are in an actor? :(
624- let ( added, exitCode) = self . addWaiter ( id: id, cont: cc)
625- if !added {
626- cc. resume ( returning: ExitStatus ( exitCode: exitCode ?? - 1 ) )
627- }
624+ self . waitForExit ( id: id, cont: cc)
628625 }
629626 let reply = message. reply ( )
630627 reply. set ( key: SandboxKeys . exitCode. rawValue, value: Int64 ( exitStatus. exitCode) )
@@ -1299,24 +1296,18 @@ extension SandboxService {
12991296 waiters [ id] = ExitWaiter ( )
13001297 }
13011298
1302- private func addWaiter( id: String , cont: CheckedContinuation < ExitStatus , Never > ) -> ( Bool , Int32 ? ) {
1303- guard let current = waiters [ id] else {
1304- // No waiter initialized at all
1305- return ( false , nil )
1306- }
1307-
1308- if current. exited ( ) {
1309- // Waiter initialzed but already exited
1310- return ( false , current. exitCode)
1299+ private func waitForExit( id: String , cont: CheckedContinuation < ExitStatus , Never > ) {
1300+ guard let waiter = waiters [ id] else {
1301+ // No waiter was initialized at all, resume immediately
1302+ cont. resume ( returning: ExitStatus ( exitCode: - 1 ) )
1303+ return
13111304 }
13121305
1313- // Waiter initialized and not exited. Guaranteed to exit later.
1314- current. register ( cont)
1315- return ( true , nil )
1306+ waiter. wait ( cont)
13161307 }
13171308
13181309 private func releaseWaiters( for id: String , status: ExitStatus ) {
1319- waiters [ id] ? . doExit ( code : status. exitCode )
1310+ waiters [ id] ? . doExit ( exitStatus : status)
13201311 }
13211312
13221313 private func setUnderlyingProcess( _ id: String , _ process: LinuxProcess ) throws {
0 commit comments