|
@@ -147,7 +147,6 @@ static void _ExecuteMainThreadRunLoopSources() {
|
|
NSMutableArray* _handlers;
|
|
NSMutableArray* _handlers;
|
|
NSInteger _activeConnections; // Accessed through _syncQueue only
|
|
NSInteger _activeConnections; // Accessed through _syncQueue only
|
|
BOOL _connected; // Accessed on main thread only
|
|
BOOL _connected; // Accessed on main thread only
|
|
- BOOL _disconnecting; // Accessed on main thread only
|
|
|
|
CFRunLoopTimerRef _disconnectTimer; // Accessed on main thread only
|
|
CFRunLoopTimerRef _disconnectTimer; // Accessed on main thread only
|
|
|
|
|
|
NSDictionary* _options;
|
|
NSDictionary* _options;
|
|
@@ -193,23 +192,11 @@ static void _ExecuteMainThreadRunLoopSources() {
|
|
GCDWebServerInitializeFunctions();
|
|
GCDWebServerInitializeFunctions();
|
|
}
|
|
}
|
|
|
|
|
|
-static void _DisconnectTimerCallBack(CFRunLoopTimerRef timer, void* info) {
|
|
|
|
- DCHECK([NSThread isMainThread]);
|
|
|
|
- GCDWebServer* server = (ARC_BRIDGE GCDWebServer*)info;
|
|
|
|
- @autoreleasepool {
|
|
|
|
- [server _didDisconnect];
|
|
|
|
- }
|
|
|
|
- server->_disconnecting = NO;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
- (instancetype)init {
|
|
- (instancetype)init {
|
|
if ((self = [super init])) {
|
|
if ((self = [super init])) {
|
|
_syncQueue = dispatch_queue_create([NSStringFromClass([self class]) UTF8String], DISPATCH_QUEUE_SERIAL);
|
|
_syncQueue = dispatch_queue_create([NSStringFromClass([self class]) UTF8String], DISPATCH_QUEUE_SERIAL);
|
|
_sourceSemaphore = dispatch_semaphore_create(0);
|
|
_sourceSemaphore = dispatch_semaphore_create(0);
|
|
_handlers = [[NSMutableArray alloc] init];
|
|
_handlers = [[NSMutableArray alloc] init];
|
|
- CFRunLoopTimerContext context = {0, (ARC_BRIDGE void*)self, NULL, NULL, NULL};
|
|
|
|
- _disconnectTimer = CFRunLoopTimerCreate(kCFAllocatorDefault, HUGE_VAL, HUGE_VAL, 0, 0, _DisconnectTimerCallBack, &context);
|
|
|
|
- CFRunLoopAddTimer(CFRunLoopGetMain(), _disconnectTimer, kCFRunLoopCommonModes);
|
|
|
|
#if TARGET_OS_IPHONE
|
|
#if TARGET_OS_IPHONE
|
|
_backgroundTask = UIBackgroundTaskInvalid;
|
|
_backgroundTask = UIBackgroundTaskInvalid;
|
|
#endif
|
|
#endif
|
|
@@ -221,9 +208,8 @@ static void _DisconnectTimerCallBack(CFRunLoopTimerRef timer, void* info) {
|
|
DCHECK(_connected == NO);
|
|
DCHECK(_connected == NO);
|
|
DCHECK(_activeConnections == 0);
|
|
DCHECK(_activeConnections == 0);
|
|
DCHECK(_options == nil); // The server can never be dealloc'ed while running because of the retain-cycle with the dispatch source
|
|
DCHECK(_options == nil); // The server can never be dealloc'ed while running because of the retain-cycle with the dispatch source
|
|
|
|
+ DCHECK(_disconnectTimer == NULL); // The server can never be dealloc'ed while the disconnect timer is pending because of the retain-cycle
|
|
|
|
|
|
- CFRunLoopTimerInvalidate(_disconnectTimer);
|
|
|
|
- CFRelease(_disconnectTimer);
|
|
|
|
ARC_RELEASE(_handlers);
|
|
ARC_RELEASE(_handlers);
|
|
ARC_DISPATCH_RELEASE(_sourceSemaphore);
|
|
ARC_DISPATCH_RELEASE(_sourceSemaphore);
|
|
ARC_DISPATCH_RELEASE(_syncQueue);
|
|
ARC_DISPATCH_RELEASE(_syncQueue);
|
|
@@ -273,9 +259,10 @@ static void _DisconnectTimerCallBack(CFRunLoopTimerRef timer, void* info) {
|
|
DCHECK(_activeConnections >= 0);
|
|
DCHECK(_activeConnections >= 0);
|
|
if (_activeConnections == 0) {
|
|
if (_activeConnections == 0) {
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
- if (_disconnecting) {
|
|
|
|
- CFRunLoopTimerSetNextFireDate(_disconnectTimer, HUGE_VAL);
|
|
|
|
- _disconnecting = NO;
|
|
|
|
|
|
+ if (_disconnectTimer) {
|
|
|
|
+ CFRunLoopTimerInvalidate(_disconnectTimer);
|
|
|
|
+ CFRelease(_disconnectTimer);
|
|
|
|
+ _disconnectTimer = NULL;
|
|
}
|
|
}
|
|
if (_connected == NO) {
|
|
if (_connected == NO) {
|
|
[self _didConnect];
|
|
[self _didConnect];
|
|
@@ -329,8 +316,17 @@ static void _DisconnectTimerCallBack(CFRunLoopTimerRef timer, void* info) {
|
|
if (_activeConnections == 0) {
|
|
if (_activeConnections == 0) {
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
if ((_disconnectDelay > 0.0) && (_source != NULL)) {
|
|
if ((_disconnectDelay > 0.0) && (_source != NULL)) {
|
|
- CFRunLoopTimerSetNextFireDate(_disconnectTimer, CFAbsoluteTimeGetCurrent() + _disconnectDelay);
|
|
|
|
- _disconnecting = YES;
|
|
|
|
|
|
+ if (_disconnectTimer) {
|
|
|
|
+ CFRunLoopTimerInvalidate(_disconnectTimer);
|
|
|
|
+ CFRelease(_disconnectTimer);
|
|
|
|
+ }
|
|
|
|
+ _disconnectTimer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent() + _disconnectDelay, 0.0, 0, 0, ^(CFRunLoopTimerRef timer) {
|
|
|
|
+ DCHECK([NSThread isMainThread]);
|
|
|
|
+ [self _didDisconnect];
|
|
|
|
+ CFRelease(_disconnectTimer);
|
|
|
|
+ _disconnectTimer = NULL;
|
|
|
|
+ });
|
|
|
|
+ CFRunLoopAddTimer(CFRunLoopGetMain(), _disconnectTimer, kCFRunLoopCommonModes);
|
|
} else {
|
|
} else {
|
|
[self _didDisconnect];
|
|
[self _didDisconnect];
|
|
}
|
|
}
|
|
@@ -592,9 +588,10 @@ static inline NSString* _EncodeBase64(NSString* string) {
|
|
_authenticationDigestAccounts = nil;
|
|
_authenticationDigestAccounts = nil;
|
|
|
|
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
- if (_disconnecting) {
|
|
|
|
- CFRunLoopTimerSetNextFireDate(_disconnectTimer, HUGE_VAL);
|
|
|
|
- _disconnecting = NO;
|
|
|
|
|
|
+ if (_disconnectTimer) {
|
|
|
|
+ CFRunLoopTimerInvalidate(_disconnectTimer);
|
|
|
|
+ CFRelease(_disconnectTimer);
|
|
|
|
+ _disconnectTimer = NULL;
|
|
[self _didDisconnect];
|
|
[self _didDisconnect];
|
|
}
|
|
}
|
|
});
|
|
});
|