From dd3f539f74aaca8da5dcab1e2b61dfcb01ae51dd Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Latour Date: Sun, 27 Apr 2014 19:05:32 -0700 Subject: [PATCH] #47 Ensure listening socket is closed when -stop returns --- GCDWebServer/Core/GCDWebServer.m | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/GCDWebServer/Core/GCDWebServer.m b/GCDWebServer/Core/GCDWebServer.m index f0ecd22..eaee5b5 100644 --- a/GCDWebServer/Core/GCDWebServer.m +++ b/GCDWebServer/Core/GCDWebServer.m @@ -47,6 +47,7 @@ @private id __unsafe_unretained _delegate; dispatch_queue_t _syncQueue; + dispatch_semaphore_t _sourceSemaphore; NSMutableArray* _handlers; NSInteger _activeConnections; // Accessed only with _syncQueue BOOL _connected; @@ -183,6 +184,7 @@ static void _ConnectedTimerCallBack(CFRunLoopTimerRef timer, void* info) { - (instancetype)init { if ((self = [super init])) { _syncQueue = dispatch_queue_create([NSStringFromClass([self class]) UTF8String], DISPATCH_QUEUE_SERIAL); + _sourceSemaphore = dispatch_semaphore_create(0); _handlers = [[NSMutableArray alloc] init]; CFRunLoopTimerContext context = {0, (ARC_BRIDGE void*)self, NULL, NULL, NULL}; _connectedTimer = CFRunLoopTimerCreate(kCFAllocatorDefault, HUGE_VAL, HUGE_VAL, 0, 0, _ConnectedTimerCallBack, &context); @@ -206,6 +208,7 @@ static void _ConnectedTimerCallBack(CFRunLoopTimerRef timer, void* info) { CFRunLoopTimerInvalidate(_connectedTimer); CFRelease(_connectedTimer); ARC_RELEASE(_handlers); + ARC_DISPATCH_RELEASE(_sourceSemaphore); ARC_DISPATCH_RELEASE(_syncQueue); ARC_DEALLOC(super); @@ -414,6 +417,7 @@ static inline NSString* _EncodeBase64(NSString* string) { LOG_DEBUG(@"Did close listening socket %i", listeningSocket); } } + dispatch_semaphore_signal(_sourceSemaphore); }); dispatch_source_set_event_handler(_source, ^{ @@ -507,7 +511,8 @@ static inline NSString* _EncodeBase64(NSString* string) { _service = NULL; } - dispatch_source_cancel(_source); // This will close the socket + dispatch_source_cancel(_source); + dispatch_semaphore_wait(_sourceSemaphore, DISPATCH_TIME_FOREVER); // Wait until the cancellation handler has been called which guarantees the listening socket is closed ARC_DISPATCH_RELEASE(_source); _source = NULL; _port = 0;