Use a lock to make |-sendQueuedWrites| a critical section
authorRobert Sesek <rsesek@bluestatic.org>
Wed, 17 Feb 2010 04:35:23 +0000 (23:35 -0500)
committerRobert Sesek <rsesek@bluestatic.org>
Wed, 17 Feb 2010 04:35:23 +0000 (23:35 -0500)
Source/GDBpConnection.h
Source/GDBpConnection.m

index ab538a45efd9b12cbde6880f7bcd9f24f9f5f3d3..f5d8de9d4ff91556e2d4db4646aa63b697fded9c 100644 (file)
        // 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_;
        
index ee885814d7f0821afc33352c99875aa46960cd80..bc52a99e459b29fa33d20b41c8cba6e8020192e7 100644 (file)
@@ -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];
 }
 
 /**