@@ -55,9 +55,9 @@ type PeerConnection struct {
55
55
56
56
idpLoginURL * string
57
57
58
- isClosed * atomicBool
59
- isNegotiationNeeded * atomicBool
60
- negotiationNeededState negotiationNeededState
58
+ isClosed * atomicBool
59
+ isNegotiationNeeded * atomicBool
60
+ updateNegotiationNeededFlagOnEmptyChain * atomicBool
61
61
62
62
lastOffer string
63
63
lastAnswer string
@@ -115,6 +115,7 @@ func (api *API) NewPeerConnection(configuration Configuration) (*PeerConnection,
115
115
// https://w3c.github.io/webrtc-pc/#constructor (Step #2)
116
116
// Some variables defined explicitly despite their implicit zero values to
117
117
// allow better readability to understand what is happening.
118
+
118
119
pc := & PeerConnection {
119
120
statsID : fmt .Sprintf ("PeerConnection-%d" , time .Now ().UnixNano ()),
120
121
configuration : Configuration {
@@ -125,18 +126,19 @@ func (api *API) NewPeerConnection(configuration Configuration) (*PeerConnection,
125
126
Certificates : []Certificate {},
126
127
ICECandidatePoolSize : 0 ,
127
128
},
128
- ops : newOperations (),
129
- isClosed : & atomicBool {},
130
- isNegotiationNeeded : & atomicBool {},
131
- negotiationNeededState : negotiationNeededStateEmpty ,
132
- lastOffer : "" ,
133
- lastAnswer : "" ,
134
- greaterMid : - 1 ,
135
- signalingState : SignalingStateStable ,
129
+ isClosed : & atomicBool {},
130
+ isNegotiationNeeded : & atomicBool {},
131
+ updateNegotiationNeededFlagOnEmptyChain : & atomicBool {},
132
+ lastOffer : "" ,
133
+ lastAnswer : "" ,
134
+ greaterMid : - 1 ,
135
+ signalingState : SignalingStateStable ,
136
136
137
137
api : api ,
138
138
log : api .settingEngine .LoggerFactory .NewLogger ("pc" ),
139
139
}
140
+ pc .ops = newOperations (pc .updateNegotiationNeededFlagOnEmptyChain , pc .onNegotiationNeeded )
141
+
140
142
pc .iceConnectionState .Store (ICEConnectionStateNew )
141
143
pc .connectionState .Store (PeerConnectionStateNew )
142
144
@@ -293,66 +295,54 @@ func (pc *PeerConnection) OnNegotiationNeeded(f func()) {
293
295
294
296
// onNegotiationNeeded enqueues negotiationNeededOp if necessary
295
297
// caller of this method should hold `pc.mu` lock
298
+ // https://www.w3.org/TR/webrtc/#dfn-update-the-negotiation-needed-flag
296
299
func (pc * PeerConnection ) onNegotiationNeeded () {
297
- // https://w3c.github.io/webrtc-pc/#updating-the-negotiation-needed-flag
298
- // non-canon step 1
299
- if pc .negotiationNeededState == negotiationNeededStateRun {
300
- pc .negotiationNeededState = negotiationNeededStateQueue
301
- return
302
- } else if pc .negotiationNeededState == negotiationNeededStateQueue {
300
+ // 4.7.3.1 If the length of connection.[[Operations]] is not 0, then set
301
+ // connection.[[UpdateNegotiationNeededFlagOnEmptyChain]] to true, and abort these steps.
302
+ if ! pc .ops .IsEmpty () {
303
+ pc .updateNegotiationNeededFlagOnEmptyChain .set (true )
303
304
return
304
305
}
305
- pc .negotiationNeededState = negotiationNeededStateRun
306
306
pc .ops .Enqueue (pc .negotiationNeededOp )
307
307
}
308
308
309
+ // https://www.w3.org/TR/webrtc/#dfn-update-the-negotiation-needed-flag
309
310
func (pc * PeerConnection ) negotiationNeededOp () {
310
- // non-canon, reset needed state machine and run again if there was a request
311
- defer func () {
312
- pc .mu .Lock ()
313
- defer pc .mu .Unlock ()
314
- if pc .negotiationNeededState == negotiationNeededStateQueue {
315
- defer pc .onNegotiationNeeded ()
316
- }
317
- pc .negotiationNeededState = negotiationNeededStateEmpty
318
- }()
319
-
320
- // Don't run NegotiatedNeeded checks if OnNegotiationNeeded is not set
321
- if handler , ok := pc .onNegotiationNeededHandler .Load ().(func ()); ! ok || handler == nil {
322
- return
323
- }
324
-
325
- // https://www.w3.org/TR/webrtc/#updating-the-negotiation-needed-flag
326
- // Step 2.1
311
+ // 4.7.3.2.1 If connection.[[IsClosed]] is true, abort these steps.
327
312
if pc .isClosed .get () {
328
313
return
329
314
}
330
- // non-canon step 2.2
315
+
316
+ // 4.7.3.2.2 If the length of connection.[[Operations]] is not 0,
317
+ // then set connection.[[UpdateNegotiationNeededFlagOnEmptyChain]] to
318
+ // true, and abort these steps.
331
319
if ! pc .ops .IsEmpty () {
332
- pc .ops . Enqueue ( pc . negotiationNeededOp )
320
+ pc .updateNegotiationNeededFlagOnEmptyChain . set ( true )
333
321
return
334
322
}
335
323
336
- // Step 2.3
324
+ // 4.7.3. 2.3 If connection's signaling state is not "stable", abort these steps.
337
325
if pc .SignalingState () != SignalingStateStable {
338
326
return
339
327
}
340
328
341
- // Step 2.4
329
+ // 4.7.3.2.4 If the result of checking if negotiation is needed is false,
330
+ // clear the negotiation-needed flag by setting connection.[[NegotiationNeeded]]
331
+ // to false, and abort these steps.
342
332
if ! pc .checkNegotiationNeeded () {
343
333
pc .isNegotiationNeeded .set (false )
344
334
return
345
335
}
346
336
347
- // Step 2.5
337
+ // 4.7.3. 2.5 If connection.[[NegotiationNeeded]] is already true, abort these steps.
348
338
if pc .isNegotiationNeeded .get () {
349
339
return
350
340
}
351
341
352
- // Step 2.6
342
+ // 4.7.3. 2.6 Set connection.[[NegotiationNeeded]] to true.
353
343
pc .isNegotiationNeeded .set (true )
354
344
355
- // Step 2.7
345
+ // 4.7.3. 2.7 Fire an event named negotiationneeded at connection.
356
346
if handler , ok := pc .onNegotiationNeededHandler .Load ().(func ()); ok && handler != nil {
357
347
handler ()
358
348
}
0 commit comments