keep the tone test output open across a reconnect
The saver reserves its output file exclusively, so opening it a second time fails. connect opened a new one per connection and a disconnect closed it, which meant the first reconnect died with "file exists" instead of resuming. Open the saver once and re-attach it on reconnect, and close it on exit instead. Detaching and closing are now separate, since only shutdown wants both. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
77fad24560
commit
5cdb2684b5
+10
-1
@@ -116,11 +116,20 @@ func (b *Barnard) cleanupConnectionAudio() {
|
|||||||
b.connectionMutex.Unlock()
|
b.connectionMutex.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Barnard) cleanupToneTestAudio() {
|
// detachToneTestAudio unsubscribes the saver without closing its output, so a
|
||||||
|
// reconnect can re-attach the same file. The saver's output is opened
|
||||||
|
// exclusively and cannot be reopened.
|
||||||
|
func (b *Barnard) detachToneTestAudio() {
|
||||||
if b.toneTestSaverDetach != nil {
|
if b.toneTestSaverDetach != nil {
|
||||||
b.toneTestSaverDetach.Detach()
|
b.toneTestSaverDetach.Detach()
|
||||||
b.toneTestSaverDetach = nil
|
b.toneTestSaverDetach = nil
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// cleanupToneTestAudio detaches the saver and closes its output. Use it when
|
||||||
|
// the client is shutting down, not between connections.
|
||||||
|
func (b *Barnard) cleanupToneTestAudio() {
|
||||||
|
b.detachToneTestAudio()
|
||||||
if b.toneTestSaver != nil {
|
if b.toneTestSaver != nil {
|
||||||
b.toneTestSaver.Stop()
|
b.toneTestSaver.Stop()
|
||||||
b.toneTestSaver = nil
|
b.toneTestSaver = nil
|
||||||
|
|||||||
@@ -61,15 +61,24 @@ func (b *Barnard) connect(reconnect bool) bool {
|
|||||||
// --- Tone test mode: skip all OpenAL; generate 440 Hz tone
|
// --- Tone test mode: skip all OpenAL; generate 440 Hz tone
|
||||||
// --- and save incoming audio to a file.
|
// --- and save incoming audio to a file.
|
||||||
|
|
||||||
// Open the output first. Starting transmission before this succeeds
|
// The output is reserved exclusively, so it can only be opened once.
|
||||||
// leaves an orphaned tone goroutine when the path is unusable.
|
// A reconnect keeps writing to the saver opened for the first
|
||||||
saver, err := NewAudioFileSaver(b.ToneTestOutput)
|
// connection instead of failing on the file that already exists.
|
||||||
if err != nil {
|
if b.toneTestSaver == nil {
|
||||||
b.exitWithError(err)
|
// Open the output first. Starting transmission before this
|
||||||
return false
|
// succeeds leaves an orphaned tone goroutine when the path is
|
||||||
|
// unusable.
|
||||||
|
saver, err := NewAudioFileSaver(b.ToneTestOutput)
|
||||||
|
if err != nil {
|
||||||
|
b.exitWithError(err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
b.toneTestSaver = saver
|
||||||
}
|
}
|
||||||
b.toneTestSaver = saver
|
// Detach any registration left over from the previous connection so
|
||||||
b.toneTestSaverDetach = b.Client.Config.AttachAudio(saver)
|
// the shared audio listener list does not grow once per reconnect.
|
||||||
|
b.detachToneTestAudio()
|
||||||
|
b.toneTestSaverDetach = b.Client.Config.AttachAudio(b.toneTestSaver)
|
||||||
|
|
||||||
b.setConnected(true)
|
b.setConnected(true)
|
||||||
if b.toneTestAutoTransmit() {
|
if b.toneTestAutoTransmit() {
|
||||||
@@ -225,7 +234,9 @@ func (b *Barnard) OnDisconnect(e *gumble.DisconnectEvent) {
|
|||||||
close(b.toneTestStop)
|
close(b.toneTestStop)
|
||||||
b.toneTestStop = nil
|
b.toneTestStop = nil
|
||||||
}
|
}
|
||||||
b.cleanupToneTestAudio()
|
// Keep the saver's output open: it was reserved exclusively and a
|
||||||
|
// reconnect re-attaches the same file. It is closed on exit.
|
||||||
|
b.detachToneTestAudio()
|
||||||
}
|
}
|
||||||
|
|
||||||
b.Notify("disconnect", "me", reason)
|
b.Notify("disconnect", "me", reason)
|
||||||
|
|||||||
@@ -445,15 +445,19 @@ func (b *Barnard) OnMicVolumeUp(ui *uiterm.Ui, key uiterm.Key) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *Barnard) OnQuitPress(ui *uiterm.Ui, key uiterm.Key) {
|
func (b *Barnard) OnQuitPress(ui *uiterm.Ui, key uiterm.Key) {
|
||||||
b.stopReconnects()
|
b.shutdown()
|
||||||
b.StopRecordingIfActive(true)
|
|
||||||
b.Client.Disconnect()
|
|
||||||
b.Ui.Close()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Barnard) CommandExit(ui *uiterm.Ui, cmd string) {
|
func (b *Barnard) CommandExit(ui *uiterm.Ui, cmd string) {
|
||||||
|
b.shutdown()
|
||||||
|
}
|
||||||
|
|
||||||
|
// shutdown releases everything that outlives a single connection, including
|
||||||
|
// the tone test saver's output file, which reconnects deliberately keep open.
|
||||||
|
func (b *Barnard) shutdown() {
|
||||||
b.stopReconnects()
|
b.stopReconnects()
|
||||||
b.StopRecordingIfActive(true)
|
b.StopRecordingIfActive(true)
|
||||||
|
b.cleanupToneTestAudio()
|
||||||
b.Client.Disconnect()
|
b.Client.Disconnect()
|
||||||
b.Ui.Close()
|
b.Ui.Close()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user