@@ -55,9 +55,9 @@ type PeerConnection struct {
5555
5656 idpLoginURL * string
5757
58- isClosed * atomicBool
59- isNegotiationNeeded * atomicBool
60- negotiationNeededState negotiationNeededState
58+ isClosed * atomicBool
59+ isNegotiationNeeded * atomicBool
60+ updateNegotiationNeededFlagOnEmptyChain * atomicBool
6161
6262 lastOffer string
6363 lastAnswer string
@@ -104,6 +104,7 @@ func (api *API) NewPeerConnection(configuration Configuration) (*PeerConnection,
104104 // https://w3c.github.io/webrtc-pc/#constructor (Step #2)
105105 // Some variables defined explicitly despite their implicit zero values to
106106 // allow better readability to understand what is happening.
107+
107108 pc := & PeerConnection {
108109 statsID : fmt .Sprintf ("PeerConnection-%d" , time .Now ().UnixNano ()),
109110 configuration : Configuration {
@@ -114,18 +115,19 @@ func (api *API) NewPeerConnection(configuration Configuration) (*PeerConnection,
114115 Certificates : []Certificate {},
115116 ICECandidatePoolSize : 0 ,
116117 },
117- ops : newOperations (),
118- isClosed : & atomicBool {},
119- isNegotiationNeeded : & atomicBool {},
120- negotiationNeededState : negotiationNeededStateEmpty ,
121- lastOffer : "" ,
122- lastAnswer : "" ,
123- greaterMid : - 1 ,
124- signalingState : SignalingStateStable ,
118+ isClosed : & atomicBool {},
119+ isNegotiationNeeded : & atomicBool {},
120+ updateNegotiationNeededFlagOnEmptyChain : & atomicBool {},
121+ lastOffer : "" ,
122+ lastAnswer : "" ,
123+ greaterMid : - 1 ,
124+ signalingState : SignalingStateStable ,
125125
126126 api : api ,
127127 log : api .settingEngine .LoggerFactory .NewLogger ("pc" ),
128128 }
129+ pc .ops = newOperations (pc .updateNegotiationNeededFlagOnEmptyChain , pc .onNegotiationNeeded )
130+
129131 pc .iceConnectionState .Store (ICEConnectionStateNew )
130132 pc .connectionState .Store (PeerConnectionStateNew )
131133
@@ -277,66 +279,54 @@ func (pc *PeerConnection) OnNegotiationNeeded(f func()) {
277279
278280// onNegotiationNeeded enqueues negotiationNeededOp if necessary
279281// caller of this method should hold `pc.mu` lock
282+ // https://www.w3.org/TR/webrtc/#dfn-update-the-negotiation-needed-flag
280283func (pc * PeerConnection ) onNegotiationNeeded () {
281- // https://w3c.github.io/webrtc-pc/#updating-the-negotiation-needed-flag
282- // non-canon step 1
283- if pc .negotiationNeededState == negotiationNeededStateRun {
284- pc .negotiationNeededState = negotiationNeededStateQueue
285- return
286- } else if pc .negotiationNeededState == negotiationNeededStateQueue {
284+ // 4.7.3.1 If the length of connection.[[Operations]] is not 0, then set
285+ // connection.[[UpdateNegotiationNeededFlagOnEmptyChain]] to true, and abort these steps.
286+ if ! pc .ops .IsEmpty () {
287+ pc .updateNegotiationNeededFlagOnEmptyChain .set (true )
287288 return
288289 }
289- pc .negotiationNeededState = negotiationNeededStateRun
290290 pc .ops .Enqueue (pc .negotiationNeededOp )
291291}
292292
293+ // https://www.w3.org/TR/webrtc/#dfn-update-the-negotiation-needed-flag
293294func (pc * PeerConnection ) negotiationNeededOp () {
294- // non-canon, reset needed state machine and run again if there was a request
295- defer func () {
296- pc .mu .Lock ()
297- defer pc .mu .Unlock ()
298- if pc .negotiationNeededState == negotiationNeededStateQueue {
299- defer pc .onNegotiationNeeded ()
300- }
301- pc .negotiationNeededState = negotiationNeededStateEmpty
302- }()
303-
304- // Don't run NegotiatedNeeded checks if OnNegotiationNeeded is not set
305- if handler , ok := pc .onNegotiationNeededHandler .Load ().(func ()); ! ok || handler == nil {
306- return
307- }
308-
309- // https://www.w3.org/TR/webrtc/#updating-the-negotiation-needed-flag
310- // Step 2.1
295+ // 4.7.3.2.1 If connection.[[IsClosed]] is true, abort these steps.
311296 if pc .isClosed .get () {
312297 return
313298 }
314- // non-canon step 2.2
299+
300+ // 4.7.3.2.2 If the length of connection.[[Operations]] is not 0,
301+ // then set connection.[[UpdateNegotiationNeededFlagOnEmptyChain]] to
302+ // true, and abort these steps.
315303 if ! pc .ops .IsEmpty () {
316- pc .ops . Enqueue ( pc . negotiationNeededOp )
304+ pc .updateNegotiationNeededFlagOnEmptyChain . set ( true )
317305 return
318306 }
319307
320- // Step 2.3
308+ // 4.7.3. 2.3 If connection's signaling state is not "stable", abort these steps.
321309 if pc .SignalingState () != SignalingStateStable {
322310 return
323311 }
324312
325- // Step 2.4
313+ // 4.7.3.2.4 If the result of checking if negotiation is needed is false,
314+ // clear the negotiation-needed flag by setting connection.[[NegotiationNeeded]]
315+ // to false, and abort these steps.
326316 if ! pc .checkNegotiationNeeded () {
327317 pc .isNegotiationNeeded .set (false )
328318 return
329319 }
330320
331- // Step 2.5
321+ // 4.7.3. 2.5 If connection.[[NegotiationNeeded]] is already true, abort these steps.
332322 if pc .isNegotiationNeeded .get () {
333323 return
334324 }
335325
336- // Step 2.6
326+ // 4.7.3. 2.6 Set connection.[[NegotiationNeeded]] to true.
337327 pc .isNegotiationNeeded .set (true )
338328
339- // Step 2.7
329+ // 4.7.3. 2.7 Fire an event named negotiationneeded at connection.
340330 if handler , ok := pc .onNegotiationNeededHandler .Load ().(func ()); ok && handler != nil {
341331 handler ()
342332 }
0 commit comments