Fix RTCAudioSession crash in removeDelegate.

BUG=

Review URL: https://codereview.webrtc.org/1877643002

Cr-Commit-Position: refs/heads/master@{#12320}
This commit is contained in:
tkchin 2016-04-11 12:00:59 -07:00 committed by Commit bot
parent 9ff9c6540b
commit efdd930dc9
2 changed files with 46 additions and 6 deletions

View File

@ -147,7 +147,8 @@ NSInteger const kRTCAudioSessionErrorConfiguration = -2;
@synchronized(self) {
_delegates.erase(std::remove(_delegates.begin(),
_delegates.end(),
delegate));
delegate),
_delegates.end());
[self removeZeroedDelegates];
}
}
@ -520,11 +521,11 @@ NSInteger const kRTCAudioSessionErrorConfiguration = -2;
- (void)removeZeroedDelegates {
@synchronized(self) {
for (auto it = _delegates.begin(); it != _delegates.end(); ++it) {
if (!*it) {
_delegates.erase(it);
}
}
_delegates.erase(
std::remove_if(_delegates.begin(),
_delegates.end(),
[](id delegate) -> bool { return delegate == nil; }),
_delegates.end());
}
}

View File

@ -46,6 +46,28 @@
@end
// A delegate that adds itself to the audio session on init and removes itself
// in its dealloc.
@interface RTCTestRemoveOnDeallocDelegate : RTCAudioSessionTestDelegate
@end
@implementation RTCTestRemoveOnDeallocDelegate
- (instancetype)init {
if (self = [super init]) {
RTCAudioSession *session = [RTCAudioSession sharedInstance];
[session addDelegate:self];
}
return self;
}
- (void)dealloc {
RTCAudioSession *session = [RTCAudioSession sharedInstance];
[session removeDelegate:self];
}
@end
@interface RTCAudioSessionTest : NSObject
@ -142,6 +164,18 @@
EXPECT_TRUE(session.delegates[0]);
}
// Tests that we don't crash when removing delegates in dealloc.
// Added as a regression test.
- (void)testRemoveDelegateOnDealloc {
@autoreleasepool {
RTCTestRemoveOnDeallocDelegate *delegate =
[[RTCTestRemoveOnDeallocDelegate alloc] init];
EXPECT_TRUE(delegate);
}
RTCAudioSession *session = [RTCAudioSession sharedInstance];
EXPECT_EQ(0u, session.delegates.size());
}
@end
namespace webrtc {
@ -176,4 +210,9 @@ TEST_F(AudioSessionTest, ZeroingWeakDelegate) {
[test testZeroingWeakDelegate];
}
TEST_F(AudioSessionTest, RemoveDelegateOnDealloc) {
RTCAudioSessionTest *test = [[RTCAudioSessionTest alloc] init];
[test testRemoveDelegateOnDealloc];
}
} // namespace webrtc