Chromium Code Reviews| Index: webrtc/sdk/objc/Framework/Classes/Common/RTCUIApplicationStatusObserver.m |
| diff --git a/webrtc/sdk/objc/Framework/Classes/Common/RTCUIApplicationStatusObserver.m b/webrtc/sdk/objc/Framework/Classes/Common/RTCUIApplicationStatusObserver.m |
| index 1d2aab48e852945fe25bd9d08a66ebb2fde9a0ac..7134773610b857304ca767662672937df4249127 100644 |
| --- a/webrtc/sdk/objc/Framework/Classes/Common/RTCUIApplicationStatusObserver.m |
| +++ b/webrtc/sdk/objc/Framework/Classes/Common/RTCUIApplicationStatusObserver.m |
| @@ -26,6 +26,7 @@ |
| @implementation RTCUIApplicationStatusObserver { |
| BOOL _initialized; |
| dispatch_block_t _initializeBlock; |
| + dispatch_semaphore_t _waitForInitializeSemaphore; |
| UIApplicationState _state; |
| id<NSObject> _activeObserver; |
| @@ -45,6 +46,12 @@ |
| return sharedInstance; |
| } |
| +// Method to make sure observers are added and the initialization block is |
| +// scheduled to run on the main queue. |
| ++ (void)prepareForUse { |
|
tkchin_webrtc
2017/09/13 18:32:02
This class feels more complex than it needs to be.
andersc
2017/09/14 08:08:45
I agree, and I mentioned a solution similar to tha
|
| + __unused RTCUIApplicationStatusObserver *observer = [self sharedInstance]; |
| +} |
| + |
| - (id)init { |
| if (self = [super init]) { |
| NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; |
| @@ -65,6 +72,7 @@ |
| [UIApplication sharedApplication].applicationState; |
| }]; |
| + _waitForInitializeSemaphore = dispatch_semaphore_create(1); |
| _initialized = NO; |
| _initializeBlock = dispatch_block_create(DISPATCH_BLOCK_INHERIT_QOS_CLASS, ^{ |
| weakSelf.state = [UIApplication sharedApplication].applicationState; |
| @@ -84,10 +92,19 @@ |
| } |
| - (BOOL)isApplicationActive { |
| + // NOTE: The function `dispatch_block_wait` can only legally be called once. |
| + // Because of this, if several threads call the `isApplicationActive` method before |
| + // the `_initializeBlock` has been executed, instead of multiple threads calling |
| + // `dispatch_block_wait`, the other threads need to wait for the first waiting thread |
| + // instead. |
| if (!_initialized) { |
| - long ret = dispatch_block_wait(_initializeBlock, |
| - dispatch_time(DISPATCH_TIME_NOW, 10.0 * NSEC_PER_SEC)); |
| - RTC_DCHECK_EQ(ret, 0); |
| + dispatch_semaphore_wait(_waitForInitializeSemaphore, DISPATCH_TIME_FOREVER); |
| + if (!_initialized) { |
| + long ret = dispatch_block_wait(_initializeBlock, |
| + dispatch_time(DISPATCH_TIME_NOW, 10.0 * NSEC_PER_SEC)); |
|
tkchin_webrtc
2017/09/13 18:32:02
What's the benefit of setting a short timeout here
andersc
2017/09/14 08:08:46
10 seconds was picked to be a long timeout. A test
|
| + RTC_DCHECK_EQ(ret, 0); |
| + } |
| + dispatch_semaphore_signal(_waitForInitializeSemaphore); |
| } |
| return _state == UIApplicationStateActive; |
| } |