Skip to content

Remove struct field inboundCall.audioOut and mirror existing transfer workflow. - #808

Open
alexfish8 wants to merge 1 commit into
tel-886/media-portfrom
afish/remove-field
Open

Remove struct field inboundCall.audioOut and mirror existing transfer workflow.#808
alexfish8 wants to merge 1 commit into
tel-886/media-portfrom
afish/remove-field

Conversation

@alexfish8

Copy link
Copy Markdown
Contributor

Addressing Denys' comment on the refactor PR.

@alexfish8
alexfish8 requested a review from a team as a code owner August 21, 2026 21:37
@alexfish8 alexfish8 changed the title Afish/remove field Remove struct field inboundCall.audioOut and mirror existing transfer workflow. Aug 21, 2026

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

Open in Devin Review

Comment thread pkg/sip/inbound.go
Comment on lines 1746 to 1754
defer func() {
if retErr != nil && !c.done.Load() {
c.lkRoom.WriteOutboundAudioTo(c.audioOut)
c.lkRoom.WriteOutboundAudioTo(oldRoomAudioOut)
} else {
if err := oldRoomAudioOut.Close(); err != nil {
c.log().Warnw("failed to close old audio output", err)
}
}
}()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Dial-tone sink closed before its writer goroutine stops

On a successful transfer, deferred cleanup closes oldRoomAudioOut before the deferred rcancel() runs, because defers execute LIFO and rcancel is registered first. The tones.Play goroutine keeps writing samples to that writer until rctx is cancelled, so it writes to the writer during and after its close.

Prompt for agents
In inboundCall.transferCall (pkg/sip/inbound.go around lines 1737-1762), the dial-tone goroutine started with tones.Play(rctx, oldRoomAudioOut, ...) keeps writing audio samples to oldRoomAudioOut until rctx is cancelled. However, the deferred cleanup that calls oldRoomAudioOut.Close() is registered after 'defer rcancel()', so due to LIFO defer ordering the Close runs before rcancel() cancels the context. This means on the success path the writer is closed while the tones.Play goroutine may still be writing to it (write-after-close race). Ensure the tone goroutine is stopped (rctx cancelled) and ideally has finished before closing oldRoomAudioOut, e.g. by cancelling and waiting for the goroutine (a done channel or WaitGroup) prior to closing, or by registering the close defer so it runs strictly after the goroutine has exited.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants