Skip to content

Fix data race on Agent.pendingBindingRequests - #1040

Open
MiniNova wants to merge 1 commit into
pion:mainfrom
MiniNova:fix/pending-binding-requests-race
Open

MiniNova wants to merge 1 commit into
pion:mainfrom
MiniNova:fix/pending-binding-requests-race

Conversation

@MiniNova

Copy link
Copy Markdown

What

Serialize all accesses to Agent.pendingBindingRequests with a dedicated
sync.Mutex.

Root cause

pendingBindingRequests (the LRU of outbound Binding-request transaction IDs)
is mutated from several places:

  • sendBindingRequest — invalidatePendingBindingRequests + append
  • handleInboundBindingResponse — invalidatePendingBindingRequests + removal
  • updateConnectionState (on Failed) — reset to make([]bindingRequest, 0)
  • revokeConsent — slices.DeleteFunc

These read-modify-write the slice header and its backing array. Under
go test -race, a suite that creates/tears down many short-lived agents
intermittently reports a data race on this field:

WARNING: DATA RACE
Write at ... by goroutine N:
  (*Agent).invalidatePendingBindingRequests() agent.go:...
  (*Agent).sendBindingRequest() agent.go:...
Current and previous write share the same call stack.

Fix

Add pendingBindingRequestsMu sync.Mutex and hold it across every mutation.

invalidatePendingBindingRequests is intentionally left unlocked: it is only
called from sendBindingRequest and handleInboundBindingResponse, both of
which already hold the mutex (locking inside it would deadlock).

How tested

  • go build ./... and go vet ./... clean.
  • Against a downstream SFU test suite under -race, the failing scenario
    (TestCallAliceBob) reproduced the race before the change and passed
    15/15 runs after it.

Notes

No API or behaviour change; only synchronization around an internal cache.

@codecov

codecov Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.70%. Comparing base (79c0411) to head (7c706d8).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1040      +/-   ##
==========================================
- Coverage   91.79%   91.70%   -0.10%     
==========================================
  Files          45       45              
  Lines        5450     5458       +8     
==========================================
+ Hits         5003     5005       +2     
- Misses        447      453       +6     
Flag Coverage Δ
go 91.70% <100.00%> (-0.10%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Serialize all accesses to Agent.pendingBindingRequests with a
dedicated mutex.

The slice is mutated from sendBindingRequest,
handleInboundBindingResponse, updateConnectionState (on failure) and
revokeConsent. invalidatePendingBindingRequests is intentionally left
unlocked because it is only called while the mutex is held.
@MiniNova
MiniNova force-pushed the fix/pending-binding-requests-race branch from 1043f40 to 7c706d8 Compare October 14, 2026 09:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant