davidliu
Committed by GitHub

Schedule PeerConnection dispose to avoid race conditions (#316)

@@ -36,7 +36,10 @@ import io.livekit.android.webrtc.getRtps @@ -36,7 +36,10 @@ import io.livekit.android.webrtc.getRtps
36 import io.livekit.android.webrtc.isConnected 36 import io.livekit.android.webrtc.isConnected
37 import kotlinx.coroutines.CoroutineDispatcher 37 import kotlinx.coroutines.CoroutineDispatcher
38 import kotlinx.coroutines.CoroutineScope 38 import kotlinx.coroutines.CoroutineScope
  39 +import kotlinx.coroutines.GlobalScope
39 import kotlinx.coroutines.SupervisorJob 40 import kotlinx.coroutines.SupervisorJob
  41 +import kotlinx.coroutines.delay
  42 +import kotlinx.coroutines.launch
40 import kotlinx.coroutines.runBlocking 43 import kotlinx.coroutines.runBlocking
41 import kotlinx.coroutines.sync.Mutex 44 import kotlinx.coroutines.sync.Mutex
42 import org.webrtc.* 45 import org.webrtc.*
@@ -263,9 +266,16 @@ constructor( @@ -263,9 +266,16 @@ constructor(
263 suspend fun close() { 266 suspend fun close() {
264 withNotClosedLock { 267 withNotClosedLock {
265 isClosed.set(true) 268 isClosed.set(true)
  269 + peerConnection.close()
  270 +
  271 + // Really ugly stop gap measure to avoid race conditions
  272 + // TODO: Properly lock any PeerConnection resources to prevent usage.
  273 + GlobalScope.launch {
  274 + delay(10L * 1000)
266 peerConnection.dispose() 275 peerConnection.dispose()
267 } 276 }
268 } 277 }
  278 + }
269 279
270 fun updateRTCConfig(config: RTCConfiguration) { 280 fun updateRTCConfig(config: RTCConfiguration) {
271 runBlocking { 281 runBlocking {
@@ -363,6 +363,7 @@ internal constructor( @@ -363,6 +363,7 @@ internal constructor(
363 363
364 val reconnectStartTime = SystemClock.elapsedRealtime() 364 val reconnectStartTime = SystemClock.elapsedRealtime()
365 for (retries in 0 until MAX_RECONNECT_RETRIES) { 365 for (retries in 0 until MAX_RECONNECT_RETRIES) {
  366 + ensureActive()
366 if (retries != 0) { 367 if (retries != 0) {
367 yield() 368 yield()
368 } 369 }
@@ -427,6 +428,7 @@ internal constructor( @@ -427,6 +428,7 @@ internal constructor(
427 } 428 }
428 } 429 }
429 430
  431 + ensureActive()
430 if (isClosed) { 432 if (isClosed) {
431 LKLog.v { "RTCEngine closed, aborting reconnection" } 433 LKLog.v { "RTCEngine closed, aborting reconnection" }
432 break 434 break
@@ -444,6 +446,7 @@ internal constructor( @@ -444,6 +446,7 @@ internal constructor(
444 } 446 }
445 } 447 }
446 448
  449 + ensureActive()
447 if (isClosed) { 450 if (isClosed) {
448 LKLog.v { "RTCEngine closed, aborting reconnection" } 451 LKLog.v { "RTCEngine closed, aborting reconnection" }
449 break 452 break
@@ -458,6 +461,7 @@ internal constructor( @@ -458,6 +461,7 @@ internal constructor(
458 delay(100) 461 delay(100)
459 } 462 }
460 463
  464 + ensureActive()
461 if (isClosed) { 465 if (isClosed) {
462 LKLog.v { "RTCEngine closed, aborting reconnection" } 466 LKLog.v { "RTCEngine closed, aborting reconnection" }
463 break 467 break