fix: 修复 waitForProcess race condition,添加调试日志
This commit is contained in:
parent
acb232d38b
commit
ec88e9f530
@ -15,6 +15,21 @@ final class ProgressState: @unchecked Sendable {
|
||||
}
|
||||
}
|
||||
|
||||
/// Thread-safe atomic boolean for one-shot guards
|
||||
final class AtomicBool: @unchecked Sendable {
|
||||
private var value = false
|
||||
private let lock = NSLock()
|
||||
|
||||
/// Returns true if this call set it from false to true (first caller wins)
|
||||
func setTrue() -> Bool {
|
||||
lock.lock()
|
||||
defer { lock.unlock() }
|
||||
guard !value else { return false }
|
||||
value = true
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
public final class FFmpegRecorder: StreamRecorderEngine {
|
||||
public weak var delegate: StreamRecorderDelegate?
|
||||
public private(set) var isRecording = false
|
||||
@ -108,6 +123,7 @@ public final class FFmpegRecorder: StreamRecorderEngine {
|
||||
|
||||
// 异步等待进程完成(不阻塞 cooperative thread)
|
||||
await waitForProcess(proc)
|
||||
NSLog("[Recorder] ffmpeg process exited, status: %d", proc.terminationStatus)
|
||||
stderrPipe.fileHandleForReading.readabilityHandler = nil
|
||||
isRecording = false
|
||||
|
||||
@ -119,9 +135,11 @@ public final class FFmpegRecorder: StreamRecorderEngine {
|
||||
throw RecordingError.outputNotFound
|
||||
}
|
||||
|
||||
NSLog("[Recorder] Analyzing output file...")
|
||||
// 分析输出文件
|
||||
let ffprobePath = ffmpegPath.replacingOccurrences(of: "ffmpeg", with: "ffprobe")
|
||||
let result = try await analyzeOutput(path: outputPath, ffprobePath: ffprobePath)
|
||||
NSLog("[Recorder] Analysis complete, notifying delegate")
|
||||
delegate?.recorder(self, didFinishWithResult: result)
|
||||
}
|
||||
|
||||
@ -141,13 +159,18 @@ public final class FFmpegRecorder: StreamRecorderEngine {
|
||||
private func waitForProcess(_ proc: Process) async {
|
||||
guard proc.isRunning else { return }
|
||||
await withCheckedContinuation { (continuation: CheckedContinuation<Void, Never>) in
|
||||
let resumed = AtomicBool()
|
||||
proc.terminationHandler = { _ in
|
||||
continuation.resume()
|
||||
if resumed.setTrue() {
|
||||
continuation.resume()
|
||||
}
|
||||
}
|
||||
// Race condition: process may have exited between isRunning check and setting handler
|
||||
if !proc.isRunning {
|
||||
proc.terminationHandler = nil
|
||||
continuation.resume()
|
||||
if resumed.setTrue() {
|
||||
continuation.resume()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user