From 45e720ad7f4c9904384bc430d2752f5318913ef7 Mon Sep 17 00:00:00 2001 From: Robert Sesek Date: Mon, 18 May 2015 08:20:28 -0400 Subject: [PATCH] Fix potential crash when detaching and reattaching. Waiting via sleep() in -[MessageQueue scheduleListenSocket] will ignore any disconnect messages, since the run loop is not being serviced. Instead, wait by pumping the loop. --- Source/DebuggerBackEnd.m | 14 ++++++++------ Source/MessageQueue.h | 3 +++ Source/MessageQueue.m | 14 ++++++++++---- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/Source/DebuggerBackEnd.m b/Source/DebuggerBackEnd.m index 81b798d..df26dd8 100644 --- a/Source/DebuggerBackEnd.m +++ b/Source/DebuggerBackEnd.m @@ -108,12 +108,14 @@ * connection as appropriate. */ - (void)setAttached:(BOOL)attached { - if (attached != attached_) { - if (!attached) - [client_ connectOnPort:port_]; - else - [client_ disconnect]; - } + if (attached == attached_) + return; + + if (attached_) + [client_ disconnect]; + else + [client_ connectOnPort:port_]; + attached_ = attached; } diff --git a/Source/MessageQueue.h b/Source/MessageQueue.h index 16961d7..a038cbd 100644 --- a/Source/MessageQueue.h +++ b/Source/MessageQueue.h @@ -33,6 +33,9 @@ NSThread* _thread; NSRunLoop* _runLoop; + // Whether or not the run loop should quit. + BOOL _shouldQuit; + // Whether or not the message queue is connected to a client. BOOL _connected; diff --git a/Source/MessageQueue.m b/Source/MessageQueue.m index 50ff99d..5778169 100644 --- a/Source/MessageQueue.m +++ b/Source/MessageQueue.m @@ -140,6 +140,7 @@ static void MessageQueueWriteEvent(CFWriteStreamRef stream, _runLoop = [NSRunLoop currentRunLoop]; _connected = NO; + _shouldQuit = NO; [self scheduleListenSocket]; // Use CFRunLoop instead of NSRunLoop because the latter has no programmatic @@ -178,8 +179,12 @@ static void MessageQueueWriteEvent(CFWriteStreamRef stream, &MessageQueueSocketAccept, // Callback function. &context); // Context to pass to callout. if (!_socket) { + // Pump the run loop while waiting for the socket to be reusued. If told + // to quit while waiting, then break out of the loop. + if (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1, FALSE) && _shouldQuit) + return; + NSLog(@"Could not open socket"); //[connection_ errorEncountered:@"Could not open socket."]; - sleep(1); } } while (!_socket); @@ -219,6 +224,7 @@ static void MessageQueueWriteEvent(CFWriteStreamRef stream, } - (void)stopRunLoop { + _shouldQuit = YES; [self disconnectClient]; CFRunLoopStop([_runLoop getCFRunLoop]); } @@ -366,9 +372,9 @@ static void MessageQueueWriteEvent(CFWriteStreamRef stream, // Set the client of the write stream. CFOptionFlags writeFlags = kCFStreamEventOpenCompleted | - kCFStreamEventCanAcceptBytes | - kCFStreamEventErrorOccurred | - kCFStreamEventEndEncountered; + kCFStreamEventCanAcceptBytes | + kCFStreamEventErrorOccurred | + kCFStreamEventEndEncountered; if (CFWriteStreamSetClient(_writeStream, writeFlags, &MessageQueueWriteEvent, &context)) // Schedule it in the run loop to receive error information. CFWriteStreamScheduleWithRunLoop(_writeStream, [_runLoop getCFRunLoop], kCFRunLoopCommonModes); -- 2.22.5