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; |
} |