Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions cmux.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -2633,6 +2633,7 @@
C0DEA771000000000000000D /* PricingPlansScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0DEA771000000000000000E /* PricingPlansScreen.swift */; };
C0DEA771000000000000000B /* ProBadgeStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0DEA771000000000000000C /* ProBadgeStyle.swift */; };
F0ACC0DE000000000000000D /* ProcessDetectedResumeIndexes.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0ACC0DE000000000000000E /* ProcessDetectedResumeIndexes.swift */; };
AC0FCEFB6665CF134634D60B /* ProcessExitWait.swift in Sources */ = {isa = PBXBuildFile; fileRef = E06E7588C05AC6A8659CFA51 /* ProcessExitWait.swift */; };
C47110010000000000000001 /* ProcessPipeReadCrashRegressionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C47110010000000000000002 /* ProcessPipeReadCrashRegressionTests.swift */; };
0A327C88E531C7E407CEF58C /* ProcessSnapshotMeasurement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4587EDAC6B63EF4846FB24A6 /* ProcessSnapshotMeasurement.swift */; };
D75280010000000000000001 /* ProfilingSignposts.swift in Sources */ = {isa = PBXBuildFile; fileRef = D75280010000000000000002 /* ProfilingSignposts.swift */; };
Expand Down Expand Up @@ -6760,6 +6761,7 @@
C0DEA771000000000000000E /* PricingPlansScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PricingPlansScreen.swift; sourceTree = "<group>"; };
C0DEA771000000000000000C /* ProBadgeStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProBadgeStyle.swift; sourceTree = "<group>"; };
F0ACC0DE000000000000000E /* ProcessDetectedResumeIndexes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProcessDetectedResumeIndexes.swift; sourceTree = "<group>"; };
E06E7588C05AC6A8659CFA51 /* ProcessExitWait.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProcessExitWait.swift; sourceTree = "<group>"; };
C47110010000000000000002 /* ProcessPipeReadCrashRegressionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProcessPipeReadCrashRegressionTests.swift; sourceTree = "<group>"; };
4587EDAC6B63EF4846FB24A6 /* ProcessSnapshotMeasurement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ProcessSnapshotMeasurement.swift"; sourceTree = "<group>"; };
D75280010000000000000002 /* ProfilingSignposts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfilingSignposts.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -11698,6 +11700,7 @@
F6724603A1B2C3D4E5F67246 /* RemoteTmuxHostRemoteCommandOverrideTests.swift */,
F6724601A1B2C3D4E5F67246 /* SSHConfiguredRemoteCommandHostTests.swift */,
4575F4BB7F52CF88AB6D0022 /* SSHStartupCommandTestSupport.swift */,
E06E7588C05AC6A8659CFA51 /* ProcessExitWait.swift */,
37B04BC7D56945E59781D11F /* SSHStartupManualReconnectTests+Fixtures.swift */,
EDF9EEAA233347858BCF3320 /* SSHConfiguredRemoteCommandHostTests+Harness.swift */,
A82715B8BDE347A18031067C /* CLINotifyProcessIntegrationRegressionTests+JSON.swift */,
Expand Down Expand Up @@ -16881,6 +16884,7 @@
F83620010000000000000001 /* PortScannerTTYFreshnessTests.swift in Sources */,
B8E9500A0000000000000001 /* PostHogAnalyticsPropertiesTests.swift in Sources */,
DE71CE00000000000000000A /* PresenceHeartbeatClientTests.swift in Sources */,
AC0FCEFB6665CF134634D60B /* ProcessExitWait.swift in Sources */,
C47110010000000000000001 /* ProcessPipeReadCrashRegressionTests.swift in Sources */,
0A327C88E531C7E407CEF58C /* ProcessSnapshotMeasurement.swift in Sources */,
A64610020000000000000001 /* QuitConfirmationAlertPresenterTests.swift in Sources */,
Expand Down
11 changes: 6 additions & 5 deletions cmuxTests/AppDelegateShortcutRoutingTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1146,17 +1146,18 @@ final class AppDelegateShortcutRoutingTests: XCTestCase {

originatingWindow.orderFront(nil)
previouslyFocusedWindow.makeKeyAndOrderFront(nil)
RunLoop.main.run(until: Date(timeIntervalSinceNow: 0.05))

XCTAssertTrue(appDelegate.shortcutRoutingKeyWindow === previouslyFocusedWindow)
// A key-window change lands on a later run-loop turn, and a loaded
// runner can take several; wait for it instead of a fixed 50 ms.
XCTAssertTrue(
waitForCondition(timeout: 5) { appDelegate.shortcutRoutingKeyWindow === previouslyFocusedWindow }
)

XCTAssertTrue(
appDelegate.toggleSidebarInActiveMainWindow(preferredWindow: originatingWindow)
)
RunLoop.main.run(until: Date(timeIntervalSinceNow: 0.05))

XCTAssertTrue(
appDelegate.shortcutRoutingKeyWindow === originatingWindow,
waitForCondition(timeout: 5) { appDelegate.shortcutRoutingKeyWindow === originatingWindow },
"An in-window action must request key status for its originating window before mutating window state"
)
XCTAssertEqual(
Expand Down
21 changes: 3 additions & 18 deletions cmuxTests/CLINotifyProcessIntegrationRegressionTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5032,12 +5032,7 @@ final class CLINotifyProcessIntegrationRegressionTests: XCTestCase {
allowBridgeResponse.signal()
XCTAssertEqual(handshakeReceived.wait(timeout: .now() + 5), .success)

let exited = DispatchSemaphore(value: 0)
DispatchQueue.global(qos: .userInitiated).async {
process.waitUntilExit()
exited.signal()
}
XCTAssertEqual(exited.wait(timeout: .now() + 5), .success)
XCTAssertEqual(waitForProcessExit(process, timeout: 5), .success)
wait(for: [socketHandled, bridgeHandled], timeout: 5)

let stderr = String(data: stderrPipe.fileHandleForReading.readDataToEndOfFile(), encoding: .utf8) ?? ""
Expand Down Expand Up @@ -5244,12 +5239,7 @@ final class CLINotifyProcessIntegrationRegressionTests: XCTestCase {
wait(for: [bridgeHandled], timeout: 5)
allowResizeResponse.signal()

let exited = DispatchSemaphore(value: 0)
DispatchQueue.global(qos: .userInitiated).async {
process.waitUntilExit()
exited.signal()
}
XCTAssertEqual(exited.wait(timeout: .now() + 5), .success)
XCTAssertEqual(waitForProcessExit(process, timeout: 5), .success)

wait(for: [socketHandled, unexpectedReadinessAfterAcknowledgement], timeout: 0.5)
let stdout = String(data: stdoutPipe.fileHandleForReading.readDataToEndOfFile(), encoding: .utf8) ?? ""
Expand Down Expand Up @@ -5436,12 +5426,7 @@ final class CLINotifyProcessIntegrationRegressionTests: XCTestCase {

closeBridge.signal()
wait(for: [bridgeHandled], timeout: 5)
let exited = DispatchSemaphore(value: 0)
DispatchQueue.global(qos: .userInitiated).async {
process.waitUntilExit()
exited.signal()
}
XCTAssertEqual(exited.wait(timeout: .now() + 5), .success)
XCTAssertEqual(waitForProcessExit(process, timeout: 5), .success)
wait(for: [socketHandled], timeout: 5)

let stdout = String(
Expand Down
9 changes: 2 additions & 7 deletions cmuxTests/CLIRemoteShellStartupPerformanceTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -395,15 +395,10 @@ struct CLIRemoteShellStartupPerformanceTests {
}

private func waitForProcess(_ running: RunningProcess, timeout: TimeInterval) -> ProcessRunResult {
let done = DispatchSemaphore(value: 0)
DispatchQueue.global(qos: .userInitiated).async {
running.process.waitUntilExit()
done.signal()
}
let timedOut = done.wait(timeout: .now() + timeout) == .timedOut
let timedOut = waitForProcessExit(running.process, timeout: timeout) == .timedOut
if timedOut {
running.process.terminate()
_ = done.wait(timeout: .now() + 1)
_ = waitForProcessExit(running.process, timeout: 1)
}
let stderr = String(data: running.stderrPipe.fileHandleForReading.readDataToEndOfFile(), encoding: .utf8) ?? ""
return ProcessRunResult(
Expand Down
7 changes: 1 addition & 6 deletions cmuxTests/CLISSHPTYResizeInputTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -149,12 +149,7 @@ struct CLISSHPTYResizeInputTests {
closeBridge.signal()
#expect(bridgeCloseObserved.wait(timeout: .now() + 5) == .success)

let exited = DispatchSemaphore(value: 0)
DispatchQueue.global(qos: .userInitiated).async {
process.waitUntilExit()
exited.signal()
}
let didExit = exited.wait(timeout: .now() + 5) == .success
let didExit = waitForProcessExit(process, timeout: 5) == .success
#expect(didExit, "Expected ssh-pty-attach to exit")
guard didExit else {
if process.isRunning {
Expand Down
11 changes: 3 additions & 8 deletions cmuxTests/CLISSHSessionAttachAnchorTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -516,18 +516,13 @@ struct CLISSHSessionAttachAnchorTests {
return ProcessRunResult(status: -1, stdout: "", stderr: String(describing: error), timedOut: false)
}

let exitSignal = DispatchSemaphore(value: 0)
DispatchQueue.global(qos: .userInitiated).async {
process.waitUntilExit()
exitSignal.signal()
}

let timedOut = exitSignal.wait(timeout: .now() + timeout) == .timedOut
let timedOut = waitForProcessExit(process, timeout: timeout) == .timedOut
if timedOut {
process.terminate()
if exitSignal.wait(timeout: .now() + 1) == .timedOut {
if waitForProcessExit(process, timeout: 1) == .timedOut {
kill(process.processIdentifier, SIGKILL)
_ = exitSignal.wait(timeout: .now() + 1)
_ = waitForProcessExit(process, timeout: 1)
}
}

Expand Down
11 changes: 3 additions & 8 deletions cmuxTests/CLISendQueuedOutputTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -201,18 +201,13 @@ struct CLISendQueuedOutputTests {
return ProcessRunResult(status: -1, stdout: "", stderr: String(describing: error), timedOut: false)
}

let exitSignal = DispatchSemaphore(value: 0)
DispatchQueue.global(qos: .userInitiated).async {
process.waitUntilExit()
exitSignal.signal()
}

let timedOut = exitSignal.wait(timeout: .now() + timeout) == .timedOut
let timedOut = waitForProcessExit(process, timeout: timeout) == .timedOut
if timedOut {
process.terminate()
if exitSignal.wait(timeout: .now() + 1) == .timedOut {
if waitForProcessExit(process, timeout: 1) == .timedOut {
kill(process.processIdentifier, SIGKILL)
_ = exitSignal.wait(timeout: .now() + 1)
_ = waitForProcessExit(process, timeout: 1)
}
}

Expand Down
16 changes: 3 additions & 13 deletions cmuxTests/CLIStdioSIGPIPERegressionTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,7 @@ final class CLIStdioSIGPIPERegressionTests: XCTestCase {
description: String,
timeout: TimeInterval = 5
) -> XCTWaiter.Result {
let exited = expectation(description: description)
DispatchQueue.global(qos: .userInitiated).async {
process.waitUntilExit()
exited.fulfill()
}
return XCTWaiter().wait(for: [exited], timeout: timeout)
waitForProcessExit(process, timeout: timeout) == .success ? .completed : .timedOut
}

private func runProcess(
Expand Down Expand Up @@ -91,16 +86,11 @@ final class CLIStdioSIGPIPERegressionTests: XCTestCase {
)
}

let exitSignal = DispatchSemaphore(value: 0)
DispatchQueue.global(qos: .userInitiated).async {
process.waitUntilExit()
exitSignal.signal()
}

let timedOut = exitSignal.wait(timeout: .now() + timeout) == .timedOut
let timedOut = waitForProcessExit(process, timeout: timeout) == .timedOut
if timedOut {
process.terminate()
_ = exitSignal.wait(timeout: .now() + 1)
_ = waitForProcessExit(process, timeout: 1)
}

let stdout = String(data: stdoutPipe.fileHandleForReading.readDataToEndOfFile(), encoding: .utf8) ?? ""
Expand Down
11 changes: 3 additions & 8 deletions cmuxTests/CLITmuxCompatStoreConcurrencyTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -206,17 +206,12 @@ struct CLITmuxCompatStoreConcurrencyTests {
return ProcessRunResult(status: -1, stderr: String(describing: error), timedOut: false)
}

let exited = DispatchSemaphore(value: 0)
DispatchQueue.global(qos: .userInitiated).async {
process.waitUntilExit()
exited.signal()
}
let timedOut = exited.wait(timeout: .now() + timeout) == .timedOut
let timedOut = waitForProcessExit(process, timeout: timeout) == .timedOut
if timedOut {
process.terminate()
if exited.wait(timeout: .now() + 1) == .timedOut {
if waitForProcessExit(process, timeout: 1) == .timedOut {
kill(process.processIdentifier, SIGKILL)
_ = exited.wait(timeout: .now() + 1)
_ = waitForProcessExit(process, timeout: 1)
}
}
let stderr = String(
Expand Down
11 changes: 3 additions & 8 deletions cmuxTests/CLIVMLayoutEnvTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -168,17 +168,12 @@ extension CLINotifyProcessIntegrationRegressionTests {
}
stdinPipe.fileHandleForWriting.write(Data(standardInput.utf8))
try? stdinPipe.fileHandleForWriting.close()
let exitSignal = DispatchSemaphore(value: 0)
DispatchQueue.global(qos: .userInitiated).async {
process.waitUntilExit()
exitSignal.signal()
}
let timedOut = exitSignal.wait(timeout: .now() + timeout) == .timedOut
let timedOut = waitForProcessExit(process, timeout: timeout) == .timedOut
if timedOut {
process.terminate()
if exitSignal.wait(timeout: .now() + 1) == .timedOut {
if waitForProcessExit(process, timeout: 1) == .timedOut {
kill(process.processIdentifier, SIGKILL)
_ = exitSignal.wait(timeout: .now() + 1)
_ = waitForProcessExit(process, timeout: 1)
}
}
let stdout = String(data: stdoutPipe.fileHandleForReading.readDataToEndOfFile(), encoding: .utf8) ?? ""
Expand Down
20 changes: 5 additions & 15 deletions cmuxTests/CMUXOpenCommandTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2930,22 +2930,17 @@ final class CMUXOpenCommandTests: XCTestCase {
return ProcessRunResult(status: -1, stdout: "", stderr: String(describing: error), timedOut: false)
}

let exitSignal = DispatchSemaphore(value: 0)
DispatchQueue.global(qos: .userInitiated).async {
process.waitUntilExit()
exitSignal.signal()
}
if let stdinText, let stdinPipe {
stdinPipe.fileHandleForWriting.write(Data(stdinText.utf8))
stdinPipe.fileHandleForWriting.closeFile()
}

let timedOut = exitSignal.wait(timeout: .now() + timeout) == .timedOut
let timedOut = waitForProcessExit(process, timeout: timeout) == .timedOut
if timedOut {
process.terminate()
if exitSignal.wait(timeout: .now() + 1) == .timedOut, process.isRunning {
if waitForProcessExit(process, timeout: 1) == .timedOut, process.isRunning {
kill(process.processIdentifier, SIGKILL)
_ = exitSignal.wait(timeout: .now() + 1)
_ = waitForProcessExit(process, timeout: 1)
}
}

Expand Down Expand Up @@ -3011,14 +3006,9 @@ final class CMUXOpenCommandTests: XCTestCase {
private func terminateProcess(_ process: Process) {
guard process.isRunning else { return }
process.terminate()
let finished = DispatchSemaphore(value: 0)
DispatchQueue.global(qos: .utility).async {
process.waitUntilExit()
finished.signal()
}
if finished.wait(timeout: .now() + 1) == .timedOut, process.isRunning {
if waitForProcessExit(process, timeout: 1) == .timedOut, process.isRunning {
kill(process.processIdentifier, SIGKILL)
_ = finished.wait(timeout: .now() + 1)
_ = waitForProcessExit(process, timeout: 1)
}
}

Expand Down
11 changes: 3 additions & 8 deletions cmuxTests/CampfireHookNotificationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -307,18 +307,13 @@ struct CampfireHookNotificationTests {
stdinPipe.fileHandleForWriting.write(Data(standardInput.utf8))
try? stdinPipe.fileHandleForWriting.close()

let exitSignal = DispatchSemaphore(value: 0)
DispatchQueue.global(qos: .userInitiated).async {
process.waitUntilExit()
exitSignal.signal()
}

let timedOut = exitSignal.wait(timeout: .now() + timeout) == .timedOut
let timedOut = waitForProcessExit(process, timeout: timeout) == .timedOut
if timedOut {
process.terminate()
if exitSignal.wait(timeout: .now() + 1) == .timedOut {
if waitForProcessExit(process, timeout: 1) == .timedOut {
kill(process.processIdentifier, SIGKILL)
_ = exitSignal.wait(timeout: .now() + 1)
_ = waitForProcessExit(process, timeout: 1)
}
}

Expand Down
11 changes: 3 additions & 8 deletions cmuxTests/CodexTerminalErrorNotificationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -264,17 +264,12 @@ private struct CodexTerminalErrorProcess {
stdin.fileHandleForWriting.write(Data(standardInput.utf8))
try? stdin.fileHandleForWriting.close()

let finished = DispatchSemaphore(value: 0)
DispatchQueue.global(qos: .userInitiated).async {
process.waitUntilExit()
finished.signal()
}
let timedOut = finished.wait(timeout: .now() + timeout) == .timedOut
let timedOut = waitForProcessExit(process, timeout: timeout) == .timedOut
if timedOut {
process.terminate()
if finished.wait(timeout: .now() + 1) == .timedOut {
if waitForProcessExit(process, timeout: 1) == .timedOut {
Darwin.kill(process.processIdentifier, SIGKILL)
guard finished.wait(timeout: .now() + 1) == .success else {
guard waitForProcessExit(process, timeout: 1) == .success else {
return Result(
status: -1,
stdout: "",
Expand Down
9 changes: 2 additions & 7 deletions cmuxTests/FishShellIntegrationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -491,16 +491,11 @@ struct FishShellIntegrationTests {
return ProcessRunResult(status: -1, stdout: "", stderr: String(describing: error), timedOut: false)
}

let exitSignal = DispatchSemaphore(value: 0)
DispatchQueue.global(qos: .userInitiated).async {
process.waitUntilExit()
exitSignal.signal()
}

let timedOut = exitSignal.wait(timeout: .now() + timeout) == .timedOut
let timedOut = waitForProcessExit(process, timeout: timeout) == .timedOut
if timedOut {
process.terminate()
_ = exitSignal.wait(timeout: .now() + 1)
_ = waitForProcessExit(process, timeout: 1)
}

return ProcessRunResult(
Expand Down
9 changes: 2 additions & 7 deletions cmuxTests/GhosttyConfigTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1397,16 +1397,11 @@ final class GhosttyConfigTests: XCTestCase {
)
}

let exitSignal = DispatchSemaphore(value: 0)
DispatchQueue.global(qos: .userInitiated).async {
process.waitUntilExit()
exitSignal.signal()
}

let timedOut = exitSignal.wait(timeout: .now() + timeout) == .timedOut
let timedOut = waitForProcessExit(process, timeout: timeout) == .timedOut
if timedOut {
process.terminate()
_ = exitSignal.wait(timeout: .now() + 1)
_ = waitForProcessExit(process, timeout: 1)
}

let stdout = String(
Expand Down
9 changes: 2 additions & 7 deletions cmuxTests/OpenCodeHookRegressionTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -227,15 +227,10 @@ const fs = require("node:fs");
} catch {
return ProcessRunResult(status: -1, stdout: "", stderr: String(describing: error), timedOut: false)
}
let exitSignal = DispatchSemaphore(value: 0)
DispatchQueue.global(qos: .userInitiated).async {
process.waitUntilExit()
exitSignal.signal()
}
let timedOut = exitSignal.wait(timeout: .now() + timeout) == .timedOut
let timedOut = waitForProcessExit(process, timeout: timeout) == .timedOut
if timedOut {
process.terminate()
_ = exitSignal.wait(timeout: .now() + 1)
_ = waitForProcessExit(process, timeout: 1)
}
return ProcessRunResult(
status: process.terminationStatus,
Expand Down
Loading
Loading