From 39ccb4b21ed0954900aeb38545b2a65f9ffdc562 Mon Sep 17 00:00:00 2001 From: Robert Sesek Date: Tue, 16 Feb 2010 23:35:23 -0500 Subject: [PATCH] Use a lock to make |-sendQueuedWrites| a critical section --- Source/GDBpConnection.h | 5 +++++ Source/GDBpConnection.m | 17 +++++++++++------ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/Source/GDBpConnection.h b/Source/GDBpConnection.h index ab538a4..f5d8de9 100644 --- a/Source/GDBpConnection.h +++ b/Source/GDBpConnection.h @@ -57,6 +57,11 @@ // array. We use this as a stack (FIFO), with index 0 being first. NSMutableArray* queuedWrites_; + // We send queued writes in multiple places, sometimes of a run loop event. + // Because of this, we need to ensure that only one client is dequeing and + // sending at a time. + NSRecursiveLock* writeQueueLock_; + // The write stream. Weak. CFWriteStreamRef writeStream_; diff --git a/Source/GDBpConnection.m b/Source/GDBpConnection.m index ee88581..bc52a99 100644 --- a/Source/GDBpConnection.m +++ b/Source/GDBpConnection.m @@ -281,6 +281,7 @@ void SocketAcceptCallback(CFSocketRef socket, transactionID = 1; stackFrames_ = [[NSMutableDictionary alloc] init]; self.queuedWrites = [NSMutableArray array]; + writeQueueLock_ = [NSRecursiveLock new]; } /** @@ -463,6 +464,7 @@ void SocketAcceptCallback(CFSocketRef socket, CFRelease(socket_); [stackFrames_ release]; self.queuedWrites = nil; + [writeQueueLock_ release]; } /** @@ -613,6 +615,7 @@ void SocketAcceptCallback(CFSocketRef socket, if (txnID != lastWrittenTransaction_) NSLog(@"txn doesn't match last written %@", response); + lastReadTransaction_ = [transaction intValue]; NSLog(@"read=%d, write=%d", lastReadTransaction_, lastWrittenTransaction_); // Dispatch the command response to an appropriate handler. @@ -645,7 +648,7 @@ void SocketAcceptCallback(CFSocketRef socket, // Load the debugger to make it look active. [delegate debuggerConnected]; - [self send:[self createCommand:@"status"]]; + // TODO: update the status. } /** @@ -805,6 +808,7 @@ void SocketAcceptCallback(CFSocketRef socket, */ - (void)sendQueuedWrites { + [writeQueueLock_ lock]; if (lastReadTransaction_ >= lastWrittenTransaction_ && [queuedWrites_ count] > 0) { NSString* command = [queuedWrites_ objectAtIndex:0]; @@ -813,12 +817,13 @@ void SocketAcceptCallback(CFSocketRef socket, // We don't want to block because this is called from the main thread. // |-performSend:| busy waits when the stream is not ready. Bail out // before we do that becuase busy waiting is BAD. - if (!CFWriteStreamCanAcceptBytes(writeStream_)) - return; - - [self performSend:command]; - [queuedWrites_ removeObjectAtIndex:0]; + if (CFWriteStreamCanAcceptBytes(writeStream_)) + { + [self performSend:command]; + [queuedWrites_ removeObjectAtIndex:0]; + } } + [writeQueueLock_ unlock]; } /** -- 2.22.5