Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 984dc2b

Browse files
authored
fix: Close peer negotiate mutex if we haven't negotiated (#1774)
Closes #1706 and #1644.
1 parent 24d1a67 commit 984dc2b

File tree

3 files changed

+22
-14
lines changed

3 files changed

+22
-14
lines changed

peer/channel.go

+9
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"io"
77
"net"
88
"sync"
9+
"time"
910

1011
"github.com/pion/datachannel"
1112
"github.com/pion/webrtc/v3"
@@ -244,6 +245,14 @@ func (c *Channel) Write(bytes []byte) (n int, err error) {
244245
if c.dc.BufferedAmount()+uint64(len(bytes)) >= maxBufferedAmount {
245246
<-c.sendMore
246247
}
248+
249+
// There's an obvious race-condition here. This is an edge-case, as
250+
// most-frequently data won't be pooled so synchronously, but is
251+
// definitely possible.
252+
//
253+
// See: https://github.com/pion/sctp/issues/181
254+
time.Sleep(time.Microsecond)
255+
247256
return c.rwc.Write(bytes)
248257
}
249258

peer/conn.go

+13-12
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ func newWithClientOrServer(servers []webrtc.ICEServer, client bool, opts *ConnOp
7373
dcFailedChannel: make(chan struct{}),
7474
localCandidateChannel: make(chan webrtc.ICECandidateInit),
7575
localSessionDescriptionChannel: make(chan webrtc.SessionDescription, 1),
76+
negotiated: make(chan struct{}),
7677
remoteSessionDescriptionChannel: make(chan webrtc.SessionDescription, 1),
7778
settingEngine: opts.SettingEngine,
7879
}
@@ -124,8 +125,7 @@ type Conn struct {
124125
localSessionDescriptionChannel chan webrtc.SessionDescription
125126
remoteSessionDescriptionChannel chan webrtc.SessionDescription
126127

127-
negotiateMutex sync.Mutex
128-
hasNegotiated bool
128+
negotiated chan struct{}
129129

130130
loggerValue atomic.Value
131131
settingEngine webrtc.SettingEngine
@@ -152,9 +152,6 @@ func (c *Conn) logger() slog.Logger {
152152
}
153153

154154
func (c *Conn) init() error {
155-
// The negotiation needed callback can take a little bit to execute!
156-
c.negotiateMutex.Lock()
157-
158155
c.rtc.OnNegotiationNeeded(c.negotiate)
159156
c.rtc.OnICEConnectionStateChange(func(iceConnectionState webrtc.ICEConnectionState) {
160157
c.closedICEMutex.Lock()
@@ -290,11 +287,13 @@ func (c *Conn) negotiate() {
290287
c.logger().Debug(context.Background(), "negotiating")
291288
// ICE candidates cannot be added until SessionDescriptions have been
292289
// exchanged between peers.
293-
if c.hasNegotiated {
294-
c.negotiateMutex.Lock()
295-
}
296-
c.hasNegotiated = true
297-
defer c.negotiateMutex.Unlock()
290+
defer func() {
291+
select {
292+
case <-c.negotiated:
293+
default:
294+
close(c.negotiated)
295+
}
296+
}()
298297

299298
if c.offerer {
300299
offer, err := c.rtc.CreateOffer(&webrtc.OfferOptions{})
@@ -368,8 +367,10 @@ func (c *Conn) AddRemoteCandidate(i webrtc.ICECandidateInit) {
368367
// This must occur in a goroutine to allow the SessionDescriptions
369368
// to be exchanged first.
370369
go func() {
371-
c.negotiateMutex.Lock()
372-
defer c.negotiateMutex.Unlock()
370+
select {
371+
case <-c.closed:
372+
case <-c.negotiated:
373+
}
373374
if c.isClosed() {
374375
return
375376
}

peer/conn_test.go

-2
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,7 @@ func TestMain(m *testing.M) {
5959
}
6060

6161
func TestConn(t *testing.T) {
62-
t.Skip("known flake -- https://github.com/coder/coder/issues/1644")
6362
t.Parallel()
64-
6563
t.Run("Ping", func(t *testing.T) {
6664
t.Parallel()
6765
client, server, _ := createPair(t)

0 commit comments

Comments
 (0)