// 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_;
@property (readonly) NSUInteger port;
@property (readonly) BOOL connected;
+@property (readonly, getter=inReconnectMode) BOOL reconnect;
@property (assign) id <DebuggerConnectionDelegate> delegate;
- (id)initWithPort:(NSUInteger)aPort;
- (void)connect;
- (void)close;
+// Marks the connection as being in "reconnect mode," which sets the expectation
+// of receiving another <init> message.
+- (void)reconnect;
+
- (void)send:(NSString*)command;
// This sends the given command format to the debugger. This method is thread
NSLog(@"SocketAcceptCallback()");
DebuggerConnection* connection = (DebuggerConnection*)connectionRaw;
-
+ if (![connection inReconnectMode])
+ return;
+
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
@synthesize port = port_;
@synthesize connected = connected_;
+@synthesize reconnect = reconnect_;
@synthesize delegate = delegate_;
@synthesize socket = socket_;
if (self = [super init])
{
port_ = aPort;
+ reconnect_ = YES;
}
return self;
}
[super dealloc];
}
+- (void)reconnect
+{
+ connected_ = NO;
+ reconnect_ = YES;
+}
+
/**
* Kicks off the socket on another thread.
*/
// 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];
// 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;
[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];
// Human-readable status of the connection.
NSString* status;
+ BOOL active_;
// The connection's delegate.
id <DebuggerProcessorDelegate> delegate;
*/
- (BOOL)isConnected
{
- return [connection_ connected];
+ return [connection_ connected] && active_;
}
// Commands ////////////////////////////////////////////////////////////////////
*/
- (void)reconnect
{
- if (connection_.connected)
- [connection_ close];
self.status = @"Connecting";
- [connection_ connect];
+ active_ = NO;
+ [connection_ reconnect];
}
/**
*/
- (void)handleInitialResponse:(NSXMLDocument*)response
{
+ active_ = YES;
+
// Register any breakpoints that exist offline.
for (Breakpoint* bp in [[BreakpointManager sharedManager] breakpoints])
[self addBreakpoint:bp];
- (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;
}
}
- (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];
}
/**