Fixed a crash in Objective-C clients when data channel becomes closed.
Objective-C applications using the data channel could crash when the following conditions were met: - The application creates a data channel and sets a data channel delegate - The delegate is deallocated but the application never clears it When this happens, the dealloc method in RTCDataChannel would reset the delegate to nil. The setDelegate: method immediately returns if the new delegate value is the same as the old one. Since the old one is a weak reference, it becomes nil, and the DataChannelDelegateAdapter is not unsubscribed from the native channel before it gets deleted. The fix removes the two optimizations, and instead subscribes the adapter to the native data channel at creation time - and unsubscribes it at dealloc time. This makes it very easy to reason about the lifetime of the subscription. Removing the optimization should have little effect on performance, as applications typically set the delegate when the channel is created. BUG= Review-Url: https://codereview.webrtc.org/1957523006 Cr-Commit-Position: refs/heads/master@{#12649}
This commit is contained in:
@ -95,7 +95,7 @@ class DataChannelDelegateAdapter : public DataChannelObserver {
|
||||
- (void)dealloc {
|
||||
// Handles unregistering the observer properly. We need to do this because
|
||||
// there may still be other references to the underlying data channel.
|
||||
self.delegate = nil;
|
||||
_nativeDataChannel->UnregisterObserver();
|
||||
}
|
||||
|
||||
- (NSString *)label {
|
||||
@ -147,21 +147,6 @@ class DataChannelDelegateAdapter : public DataChannelObserver {
|
||||
return _nativeDataChannel->buffered_amount();
|
||||
}
|
||||
|
||||
- (void)setDelegate:(id<RTCDataChannelDelegate>)delegate {
|
||||
if (_delegate == delegate) {
|
||||
return;
|
||||
}
|
||||
if (_isObserverRegistered) {
|
||||
_nativeDataChannel->UnregisterObserver();
|
||||
_isObserverRegistered = NO;
|
||||
}
|
||||
_delegate = delegate;
|
||||
if (_delegate) {
|
||||
_nativeDataChannel->RegisterObserver(_observer.get());
|
||||
_isObserverRegistered = YES;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)close {
|
||||
_nativeDataChannel->Close();
|
||||
}
|
||||
@ -186,6 +171,7 @@ class DataChannelDelegateAdapter : public DataChannelObserver {
|
||||
if (self = [super init]) {
|
||||
_nativeDataChannel = nativeDataChannel;
|
||||
_observer.reset(new webrtc::DataChannelDelegateAdapter(self));
|
||||
_nativeDataChannel->RegisterObserver(_observer.get());
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user