Move dealing with the socket into NetworkCallbackController.
authorRobert Sesek <rsesek@bluestatic.org>
Sat, 19 Feb 2011 17:40:42 +0000 (12:40 -0500)
committerRobert Sesek <rsesek@bluestatic.org>
Sat, 19 Feb 2011 17:40:42 +0000 (12:40 -0500)
Source/DebuggerBackEnd.h
Source/DebuggerBackEnd.m
Source/DebuggerController.m
Source/NetworkCallbackController.h
Source/NetworkCallbackController.mm
Source/NetworkConnection.h
Source/NetworkConnection.mm
Source/NetworkConnectionPrivate.h

index f95a4ed7db7eb4ed1e84cc4457c346caf26a1f5d..255b585fcc2761f7c418273ee27e92bfaf267747 100644 (file)
@@ -80,6 +80,7 @@
 - (void)stepIn;
 - (void)stepOut;
 - (void)stepOver;
+- (void)stop;
 - (void)detach;
 
 // Breakpoint management.
index 96ca92b76056e1967f2992979635508f752b7f06..92cd9d578da5fed26e8e45aec82658277aa510be 100644 (file)
   [self recordCallback:@selector(debuggerStep:) forTransaction:tx];
 }
 
+/**
+ * Halts execution of the script.
+ */
+- (void)stop
+{
+  [connection_ close];
+  active_ = NO;
+  self.status = @"Stopped";
+  if ([delegate respondsToSelector:@selector(debuggerDisconnected)])
+    [delegate debuggerDisconnected];
+}
+
 /**
  * Ends the current debugging session.
  */
index efd037ea1bc41d8ee82ec82c25d1902e5ed39118..db02575e7bb7c6f8207022cccbc87f28199c46de 100644 (file)
  */
 - (IBAction)stop:(id)sender
 {
-  [connection detach];
+  [connection stop];
 }
 
 - (void)fetchChildProperties:(VariableNode*)node
index d8da7d5bbcd1a958b9a1f6a0998e2cc8d40d0adb..de6cc327f567ec17e26e1071673437b54cc2bcf0 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 #import <CoreFoundation/CoreFoundation.h>
+#import <Foundation/Foundation.h>
 
 @class NetworkConnection;
 
@@ -29,6 +30,13 @@ class NetworkCallbackController
   // thread.
   NetworkCallbackController(NetworkConnection* connection);
 
+  // Creates a socket and schedules it on the current run loop.
+  void OpenConnection(NSUInteger port);
+
+  // Closes down the read/write streams.
+  void CloseConnection();
+
+ private:
   // These static methods forward an invocation to the instance methods. The
   // last void pointer, named |self|, is the instance of this class.
   static void SocketAcceptCallback(CFSocketRef socket,
@@ -43,7 +51,6 @@ class NetworkCallbackController
                                   CFStreamEventType eventType,
                                   void* self);
 
- private:
   void OnSocketAccept(CFSocketRef socket,
                       CFDataRef address,
                       const void* data);
@@ -57,7 +64,10 @@ class NetworkCallbackController
 
   // Messages the NetworkConnection's delegate and takes ownership of |error|.
   void ReportError(CFErrorRef error);
-  
+
+  // The actual socket.
+  CFSocketRef socket_;  // Strong.
+
   NetworkConnection* connection_;  // Weak, owns this.
   CFRunLoopRef runLoop_;  // Weak.
 };
index 28958ed433d5ca892235bbb8bdc5cf5dfa14c1f7..b2d79f2c8d46db6b4444303089143e026b2e8559 100644 (file)
@@ -16,6 +16,9 @@
 
 #import "NetworkCallbackController.h"
 
+#import <sys/socket.h>
+#import <netinet/in.h>
+
 #import "NetworkConnection.h"
 #import "NetworkConnectionPrivate.h"
 
@@ -25,6 +28,63 @@ NetworkCallbackController::NetworkCallbackController(NetworkConnection* connecti
 {
 }
 
+void NetworkCallbackController::OpenConnection(NSUInteger port)
+{
+  // Pass ourselves to the callback so we don't have to use ugly globals.
+  CFSocketContext context = { 0 };
+  context.info = this;
+  
+  // Create the address structure.
+  struct sockaddr_in address;
+  memset(&address, 0, sizeof(address));
+  address.sin_len = sizeof(address);
+  address.sin_family = AF_INET;
+  address.sin_port = htons(port);
+  address.sin_addr.s_addr = htonl(INADDR_ANY);    
+  
+  // Create the socket signature.
+  CFSocketSignature signature;
+  signature.protocolFamily = PF_INET;
+  signature.socketType = SOCK_STREAM;
+  signature.protocol = IPPROTO_TCP;
+  signature.address = (CFDataRef)[NSData dataWithBytes:&address length:sizeof(address)];
+  
+  do {
+    socket_ = CFSocketCreateWithSocketSignature(kCFAllocatorDefault,
+                                                &signature,  // Socket signature.
+                                                kCFSocketAcceptCallBack,  // Callback types.
+                                                &NetworkCallbackController::SocketAcceptCallback,  // Callout function pointer.
+                                                &context);  // Context to pass to callout.
+    if (!socket_) {
+      [connection_ errorEncountered:@"Could not open socket."];
+      sleep(1);
+    }
+  } while (!socket_);
+  
+  // Allow old, yet-to-be recycled sockets to be reused.
+  BOOL yes = YES;
+  setsockopt(CFSocketGetNative(socket_), SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(BOOL));
+  setsockopt(CFSocketGetNative(socket_), SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(BOOL));
+  
+  // Schedule the socket on the run loop.
+  CFRunLoopSourceRef source = CFSocketCreateRunLoopSource(kCFAllocatorDefault, socket_, 0);
+  CFRunLoopAddSource(runLoop_, source, kCFRunLoopCommonModes);
+  CFRelease(source);  
+}
+
+void NetworkCallbackController::CloseConnection()
+{
+  if (socket_) {
+    NSLog(@"invalidating socket %d", close(CFSocketGetNative(socket_)));
+    CFSocketInvalidate(socket_);
+    NSLog(@"socket is valid %d", CFSocketIsValid(socket_));
+    CFRelease(socket_);
+    socket_ = NULL;
+  }  
+  UnscheduleReadStream();
+  UnscheduleWriteStream();
+}
+
 // Static Methods //////////////////////////////////////////////////////////////
 
 void NetworkCallbackController::SocketAcceptCallback(CFSocketRef socket,
@@ -116,15 +176,18 @@ void NetworkCallbackController::OnReadStreamEvent(CFReadStreamRef stream,
   switch (eventType)
   {
     case kCFStreamEventHasBytesAvailable:
-      [connection_ readStreamHasData];
+      if (connection_.readStream)
+        [connection_ readStreamHasData];
       break;
       
     case kCFStreamEventErrorOccurred:
+      NSLog(@"%s error", __PRETTY_FUNCTION__);
       ReportError(CFReadStreamCopyError(stream));
       UnscheduleReadStream();
       break;
       
     case kCFStreamEventEndEncountered:
+      NSLog(@"%s end", __PRETTY_FUNCTION__);
       UnscheduleReadStream();
       [connection_ socketDisconnected];
       break;
index efd01633b15b6d65f3c68bdd4d0f7db62a9ce478..d34d7cec61361ae90bcbb0624603e4eabd99abf9 100644 (file)
@@ -46,9 +46,6 @@ class NetworkCallbackController;
   // Internal class that manages CFNetwork callbacks. Strong.
   NetworkCallbackController* callbackController_;
 
-  // The raw CFSocket on which the two streams are based. Strong.
-  CFSocketRef socket_;
-  
   // The read stream that is scheduled on the main run loop. Weak.
   CFReadStreamRef readStream_;
   
index 41227d31056bb122dc8413303d2b8c81313ded23..894b1d79510c18e89d4bdcb3b10489795482b18f 100644 (file)
@@ -17,9 +17,6 @@
 #import "NetworkConnection.h"
 #import "NetworkConnectionPrivate.h"
 
-#import <sys/socket.h>
-#import <netinet/in.h>
-
 #import "AppDelegate.h"
 #import "LoggingController.h"
 #include "NetworkCallbackController.h"
@@ -40,7 +37,6 @@ void PerformQuitSignal(void* info)
 @synthesize connected = connected_;
 @synthesize delegate = delegate_;
 
-@synthesize socket = socket_;
 @synthesize readStream = readStream_;
 @synthesize lastReadTransaction = lastReadTransaction_;
 @synthesize currentPacket = currentPacket_;
@@ -88,47 +84,6 @@ void PerformQuitSignal(void* info)
   runLoop_ = [NSRunLoop currentRunLoop];
   callbackController_ = new NetworkCallbackController(self);
 
-  // Pass ourselves to the callback so we don't have to use ugly globals.
-  CFSocketContext context = { 0 };
-  context.info = callbackController_;
-  
-  // Create the address structure.
-  struct sockaddr_in address;
-  memset(&address, 0, sizeof(address));
-  address.sin_len = sizeof(address);
-  address.sin_family = AF_INET;
-  address.sin_port = htons(port_);
-  address.sin_addr.s_addr = htonl(INADDR_ANY);    
-  
-  // Create the socket signature.
-  CFSocketSignature signature;
-  signature.protocolFamily = PF_INET;
-  signature.socketType = SOCK_STREAM;
-  signature.protocol = IPPROTO_TCP;
-  signature.address = (CFDataRef)[NSData dataWithBytes:&address length:sizeof(address)];
-
-  do {
-    socket_ = CFSocketCreateWithSocketSignature(kCFAllocatorDefault,
-                                                &signature,  // Socket signature.
-                                                kCFSocketAcceptCallBack,  // Callback types.
-                                                &NetworkCallbackController::SocketAcceptCallback,  // Callout function pointer.
-                                                &context);  // Context to pass to callout.
-    if (!socket_) {
-      [self errorEncountered:@"Could not open socket."];
-      sleep(1);
-    }
-  } while (!socket_);
-  
-  // Allow old, yet-to-be recycled sockets to be reused.
-  BOOL yes = YES;
-  setsockopt(CFSocketGetNative(socket_), SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(BOOL));
-  setsockopt(CFSocketGetNative(socket_), SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(BOOL));
-  
-  // Schedule the socket on the run loop.
-  CFRunLoopSourceRef source = CFSocketCreateRunLoopSource(kCFAllocatorDefault, socket_, 0);
-  CFRunLoopAddSource([runLoop_ getCFRunLoop], source, kCFRunLoopCommonModes);
-  CFRelease(source);
-
   // Create a source that is used to quit.
   CFRunLoopSourceContext quitContext = { 0 };
   quitContext.info = self;
@@ -136,6 +91,8 @@ void PerformQuitSignal(void* info)
   quitSource_ = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &quitContext);
   CFRunLoopAddSource([runLoop_ getCFRunLoop], quitSource_, kCFRunLoopCommonModes);
 
+  callbackController_->OpenConnection(port_);
+
   CFRunLoopRun();
 
   thread_ = nil;
@@ -195,14 +152,8 @@ void PerformQuitSignal(void* info)
   if (runLoop_) {
     CFRunLoopStop([runLoop_ getCFRunLoop]);
   }
-  
-  // The socket goes down, so do the streams, which clean themselves up.
-  if (socket_) {
-    NSLog(@"invalidating socket");
-    CFSocketInvalidate(socket_);
-    CFRelease(socket_);
-    socket_ = NULL;
-  }
+
+  callbackController_->CloseConnection();
 }
 
 /**
index 5cf9070124e5e5a6c12121b27fdbd5b3d69b4d26..3b8f7f462da72b499512e6fc669eb712cc4c1235 100644 (file)
@@ -20,7 +20,6 @@
 // by the C++ NetworkCallbackController to communicate.
 @interface NetworkConnection ()
 
-@property (assign) CFSocketRef socket;
 @property (assign) CFReadStreamRef readStream;
 @property NSUInteger lastReadTransaction;
 @property (retain) NSMutableString* currentPacket;