Rework cleanup of peer connection client delegates.

This commit is contained in:
Matthew Chen 2018-05-15 10:46:03 -04:00
parent 547605885e
commit 3d5cbb73fb

View file

@ -91,12 +91,6 @@ class PeerConnectionClient: NSObject, RTCPeerConnectionDelegate, RTCDataChannelD
// Delegate is notified of key events in the call lifecycle. // Delegate is notified of key events in the call lifecycle.
private weak var delegate: PeerConnectionClientDelegate! private weak var delegate: PeerConnectionClientDelegate!
func setDelegate(delegate: PeerConnectionClientDelegate?) {
PeerConnectionClient.signalingQueue.async {
self.delegate = delegate
}
}
// Connection // Connection
private var peerConnection: RTCPeerConnection! private var peerConnection: RTCPeerConnection!
@ -271,12 +265,13 @@ class PeerConnectionClient: NSObject, RTCPeerConnectionDelegate, RTCDataChannelD
videoCaptureSession.stopRunning() videoCaptureSession.stopRunning()
} }
if let delegate = self.delegate { DispatchQueue.main.async { [weak self, weak localVideoTrack] in
DispatchQueue.main.async { [weak self, weak localVideoTrack] in guard let strongSelf = self else { return }
guard let strongSelf = self else { return } guard let strongLocalVideoTrack = localVideoTrack else { return }
guard let strongLocalVideoTrack = localVideoTrack else { return } objc_sync_enter(strongSelf)
delegate.peerConnectionClient(strongSelf, didUpdateLocal: enabled ? strongLocalVideoTrack : nil) guard let strongDelegate = strongSelf.delegate else { return }
} objc_sync_exit(strongSelf)
strongDelegate.peerConnectionClient(strongSelf, didUpdateLocal: enabled ? strongLocalVideoTrack : nil)
} }
} }
} }
@ -496,6 +491,12 @@ class PeerConnectionClient: NSObject, RTCPeerConnectionDelegate, RTCDataChannelD
SwiftAssertIsOnMainThread(#function) SwiftAssertIsOnMainThread(#function)
Logger.debug("\(TAG) in \(#function)") Logger.debug("\(TAG) in \(#function)")
// Clear the delegate immediately so that we can guarantee that
// no delegate methods are called after terminate() returns.
objc_sync_enter(self)
delegate = nil
objc_sync_exit(self)
PeerConnectionClient.signalingQueue.async { PeerConnectionClient.signalingQueue.async {
assert(self.peerConnection != nil) assert(self.peerConnection != nil)
self.terminateInternal() self.terminateInternal()
@ -536,9 +537,10 @@ class PeerConnectionClient: NSObject, RTCPeerConnectionDelegate, RTCDataChannelD
peerConnection.delegate = nil peerConnection.delegate = nil
peerConnection.close() peerConnection.close()
peerConnection = nil peerConnection = nil
objc_sync_exit(self)
assert(delegate == nil)
delegate = nil delegate = nil
objc_sync_exit(self)
} }
// MARK: - Data Channel // MARK: - Data Channel
@ -608,11 +610,12 @@ class PeerConnectionClient: NSObject, RTCPeerConnectionDelegate, RTCDataChannelD
return return
} }
if let delegate = self.delegate { DispatchQueue.main.async { [weak self] in
DispatchQueue.main.async { [weak self] in guard let strongSelf = self else { return }
guard let strongSelf = self else { return } objc_sync_enter(strongSelf)
delegate.peerConnectionClient(strongSelf, received: dataChannelMessage) guard let strongDelegate = strongSelf.delegate else { return }
} objc_sync_exit(strongSelf)
strongDelegate.peerConnectionClient(strongSelf, received: dataChannelMessage)
} }
} }
} }
@ -652,22 +655,23 @@ class PeerConnectionClient: NSObject, RTCPeerConnectionDelegate, RTCDataChannelD
return return
} }
if let delegate = self.delegate { DispatchQueue.main.async { [weak self] in
DispatchQueue.main.async { [weak self] in guard let strongSelf = self else { return }
guard let strongSelf = self else { return } objc_sync_enter(strongSelf)
guard let strongDelegate = strongSelf.delegate else { return }
objc_sync_exit(strongSelf)
// See the comments on the remoteVideoTrack property. // See the comments on the remoteVideoTrack property.
// //
// We only access the remoteVideoTrack property if peerConnection is non-nil. // We only access the remoteVideoTrack property if peerConnection is non-nil.
var remoteVideoTrack: RTCVideoTrack? var remoteVideoTrack: RTCVideoTrack?
objc_sync_enter(strongSelf) objc_sync_enter(strongSelf)
if strongSelf.peerConnection != nil { if strongSelf.peerConnection != nil {
remoteVideoTrack = strongSelf.remoteVideoTrack remoteVideoTrack = strongSelf.remoteVideoTrack
}
objc_sync_exit(strongSelf)
delegate.peerConnectionClient(strongSelf, didUpdateRemote: remoteVideoTrack)
} }
objc_sync_exit(strongSelf)
strongDelegate.peerConnectionClient(strongSelf, didUpdateRemote: remoteVideoTrack)
} }
} }
} }
@ -692,27 +696,30 @@ class PeerConnectionClient: NSObject, RTCPeerConnectionDelegate, RTCDataChannelD
Logger.info("\(self.TAG) didChange IceConnectionState:\(newState.debugDescription)") Logger.info("\(self.TAG) didChange IceConnectionState:\(newState.debugDescription)")
switch newState { switch newState {
case .connected, .completed: case .connected, .completed:
if let delegate = self.delegate { DispatchQueue.main.async { [weak self] in
DispatchQueue.main.async { [weak self] in guard let strongSelf = self else { return }
guard let strongSelf = self else { return } objc_sync_enter(strongSelf)
delegate.peerConnectionClientIceConnected(strongSelf) guard let strongDelegate = strongSelf.delegate else { return }
} objc_sync_exit(strongSelf)
strongDelegate.peerConnectionClientIceConnected(strongSelf)
} }
case .failed: case .failed:
Logger.warn("\(self.TAG) RTCIceConnection failed.") Logger.warn("\(self.TAG) RTCIceConnection failed.")
if let delegate = self.delegate { DispatchQueue.main.async { [weak self] in
DispatchQueue.main.async { [weak self] in guard let strongSelf = self else { return }
guard let strongSelf = self else { return } objc_sync_enter(strongSelf)
delegate.peerConnectionClientIceFailed(strongSelf) guard let strongDelegate = strongSelf.delegate else { return }
} objc_sync_exit(strongSelf)
strongDelegate.peerConnectionClientIceFailed(strongSelf)
} }
case .disconnected: case .disconnected:
Logger.warn("\(self.TAG) RTCIceConnection disconnected.") Logger.warn("\(self.TAG) RTCIceConnection disconnected.")
if let delegate = self.delegate { DispatchQueue.main.async { [weak self] in
DispatchQueue.main.async { [weak self] in guard let strongSelf = self else { return }
guard let strongSelf = self else { return } objc_sync_enter(strongSelf)
delegate.peerConnectionClientIceDisconnected(strongSelf) guard let strongDelegate = strongSelf.delegate else { return }
} objc_sync_exit(strongSelf)
strongDelegate.peerConnectionClientIceDisconnected(strongSelf)
} }
default: default:
Logger.debug("\(self.TAG) ignoring change IceConnectionState:\(newState.debugDescription)") Logger.debug("\(self.TAG) ignoring change IceConnectionState:\(newState.debugDescription)")
@ -733,11 +740,12 @@ class PeerConnectionClient: NSObject, RTCPeerConnectionDelegate, RTCDataChannelD
return return
} }
Logger.info("\(self.TAG) adding local ICE candidate:\(candidate.sdp)") Logger.info("\(self.TAG) adding local ICE candidate:\(candidate.sdp)")
if let delegate = self.delegate { DispatchQueue.main.async { [weak self] in
DispatchQueue.main.async { [weak self] in guard let strongSelf = self else { return }
guard let strongSelf = self else { return } objc_sync_enter(strongSelf)
delegate.peerConnectionClient(strongSelf, addedLocalIceCandidate: candidate) guard let strongDelegate = strongSelf.delegate else { return }
} objc_sync_exit(strongSelf)
strongDelegate.peerConnectionClient(strongSelf, addedLocalIceCandidate: candidate)
} }
} }
} }