From 4f0f6c41220648181f2de6face346c027f37f3d0 Mon Sep 17 00:00:00 2001 From: Robert Sesek Date: Sun, 31 Oct 2010 19:28:20 -0400 Subject: [PATCH] Do not ever close the socket until we are definitely closing the connection. We can't reuse the same socket fast enough. --- Source/DebuggerConnection.h | 8 ++++++++ Source/DebuggerConnection.m | 26 +++++++++++++++-------- Source/DebuggerProcessor.h | 1 + Source/DebuggerProcessor.m | 41 +++++++++++++++++-------------------- 4 files changed, 45 insertions(+), 31 deletions(-) diff --git a/Source/DebuggerConnection.h b/Source/DebuggerConnection.h index 01c2bb1..87029a1 100644 --- a/Source/DebuggerConnection.h +++ b/Source/DebuggerConnection.h @@ -31,6 +31,9 @@ // If the connection to the debugger engine is currently active. BOOL connected_; + // Whether or not in reconnect mode. + BOOL reconnect_; + // The thread on which network operations are performed. Weak. NSThread* thread_; @@ -81,6 +84,7 @@ @property (readonly) NSUInteger port; @property (readonly) BOOL connected; +@property (readonly, getter=inReconnectMode) BOOL reconnect; @property (assign) id delegate; - (id)initWithPort:(NSUInteger)aPort; @@ -88,6 +92,10 @@ - (void)connect; - (void)close; +// Marks the connection as being in "reconnect mode," which sets the expectation +// of receiving another message. +- (void)reconnect; + - (void)send:(NSString*)command; // This sends the given command format to the debugger. This method is thread diff --git a/Source/DebuggerConnection.m b/Source/DebuggerConnection.m index 1149d56..3b28250 100644 --- a/Source/DebuggerConnection.m +++ b/Source/DebuggerConnection.m @@ -123,7 +123,9 @@ void SocketAcceptCallback(CFSocketRef socket, NSLog(@"SocketAcceptCallback()"); DebuggerConnection* connection = (DebuggerConnection*)connectionRaw; - + if (![connection inReconnectMode]) + return; + CFReadStreamRef readStream; CFWriteStreamRef writeStream; @@ -200,6 +202,7 @@ void PerformQuitSignal(void* info) @synthesize port = port_; @synthesize connected = connected_; +@synthesize reconnect = reconnect_; @synthesize delegate = delegate_; @synthesize socket = socket_; @@ -215,6 +218,7 @@ void PerformQuitSignal(void* info) if (self = [super init]) { port_ = aPort; + reconnect_ = YES; } return self; } @@ -225,6 +229,12 @@ void PerformQuitSignal(void* info) [super dealloc]; } +- (void)reconnect +{ + connected_ = NO; + reconnect_ = YES; +} + /** * Kicks off the socket on another thread. */ @@ -373,7 +383,7 @@ void PerformQuitSignal(void* info) // through normal disconnected procedure (a call to |-close|, followed by // the downing of the socket and the stream, which also produces this // messsage). Instead, the stream callbacks encountered EOF unexpectedly. - [self close]; + //[self close]; } if ([delegate_ respondsToSelector:@selector(connectionDidClose:)]) [delegate_ connectionDidClose:self]; @@ -618,13 +628,10 @@ void PerformQuitSignal(void* info) // Otherwise, assume +1 and hope it works. ++lastReadTransaction_; - } - else - { + } else if (!reconnect_) { // See if the transaction can be parsed out. NSInteger transaction = [self transactionIDFromResponse:xmlTest]; - if (transaction < lastReadTransaction_) - { + if (transaction < lastReadTransaction_) { NSLog(@"tx = %d vs %d", transaction, lastReadTransaction_); NSLog(@"out of date transaction %@", packet); return; @@ -655,8 +662,9 @@ void PerformQuitSignal(void* info) [self errorEncountered:errorMessage]; } - if ([[[response rootElement] name] isEqualToString:@"init"]) - { + if ([[[response rootElement] name] isEqualToString:@"init"]) { + connected_ = YES; + reconnect_ = NO; [delegate_ performSelectorOnMainThread:@selector(handleInitialResponse:) withObject:response waitUntilDone:NO]; diff --git a/Source/DebuggerProcessor.h b/Source/DebuggerProcessor.h index dee8a2e..1059a33 100644 --- a/Source/DebuggerProcessor.h +++ b/Source/DebuggerProcessor.h @@ -36,6 +36,7 @@ // Human-readable status of the connection. NSString* status; + BOOL active_; // The connection's delegate. id delegate; diff --git a/Source/DebuggerProcessor.m b/Source/DebuggerProcessor.m index c392d32..8af726b 100644 --- a/Source/DebuggerProcessor.m +++ b/Source/DebuggerProcessor.m @@ -105,7 +105,7 @@ */ - (BOOL)isConnected { - return [connection_ connected]; + return [connection_ connected] && active_; } // Commands //////////////////////////////////////////////////////////////////// @@ -117,10 +117,9 @@ */ - (void)reconnect { - if (connection_.connected) - [connection_ close]; self.status = @"Connecting"; - [connection_ connect]; + active_ = NO; + [connection_ reconnect]; } /** @@ -233,6 +232,8 @@ */ - (void)handleInitialResponse:(NSXMLDocument*)response { + active_ = YES; + // Register any breakpoints that exist offline. for (Breakpoint* bp in [[BreakpointManager sharedManager] breakpoints]) [self addBreakpoint:bp]; @@ -262,12 +263,13 @@ - (void)updateStatus:(NSXMLDocument*)response { self.status = [[[[response rootElement] attributeForName:@"status"] stringValue] capitalizedString]; - if (status == nil || [status isEqualToString:@"Stopped"] || [status isEqualToString:@"Stopping"]) - { - [connection_ close]; + active_ = YES; + if (!status || [status isEqualToString:@"Stopped"]) { [delegate debuggerDisconnected]; - - self.status = @"Stopped"; + active_ = NO; + } else if ([status isEqualToString:@"Stopping"]) { + [connection_ sendCommandWithFormat:@"stop"]; + active_ = NO; } } @@ -278,22 +280,17 @@ - (void)debuggerStep:(NSXMLDocument*)response { [self updateStatus:response]; - if (![connection_ connected]) + if (![self isConnected]) return; - + // If this is the run command, tell the delegate that a bunch of updates // are coming. Also remove all existing stack routes and request a new stack. - // TODO: figure out if we can not clobber the stack every time. - NSString* command = [[[response rootElement] attributeForName:@"command"] stringValue]; - if (YES || [command isEqualToString:@"run"]) - { - if ([delegate respondsToSelector:@selector(clobberStack)]) - [delegate clobberStack]; - [stackFrames_ removeAllObjects]; - NSNumber* tx = [connection_ sendCommandWithFormat:@"stack_depth"]; - [self recordCallback:@selector(rebuildStack:) forTransaction:tx]; - stackFirstTransactionID_ = [tx intValue]; - } + if ([delegate respondsToSelector:@selector(clobberStack)]) + [delegate clobberStack]; + [stackFrames_ removeAllObjects]; + NSNumber* tx = [connection_ sendCommandWithFormat:@"stack_depth"]; + [self recordCallback:@selector(rebuildStack:) forTransaction:tx]; + stackFirstTransactionID_ = [tx intValue]; } /** -- 2.22.5