Mmmmmm..... oneway void
authorAlexander Strange <astrange@ithinksw.com>
Mon, 17 Mar 2003 06:32:45 +0000 (06:32 +0000)
committerAlexander Strange <astrange@ithinksw.com>
Mon, 17 Mar 2003 06:32:45 +0000 (06:32 +0000)
ITByteStream.h
ITInetServerSocket.h
ITInetServerSocket.m
ITInetSocket.h
ITInetSocket.m

index 52297c5..52f4856 100755 (executable)
@@ -11,7 +11,7 @@
 @class ITByteStream;
 
 @protocol ITByteStreamDelegate
--(void)newDataAdded:(ITByteStream *)sender;
+-(oneway void)newDataAdded:(ITByteStream *)sender;
 @end
 
 @interface ITByteStream : NSObject {
index 3185a66..5f8a479 100755 (executable)
@@ -17,6 +17,7 @@
 @interface ITInetServerSocket : NSObject {
     @private
     int sockfd;
+    volatile int dieflag;
     NSMutableSet *clients;
     NSNetService *service;
     id delegate;
index c37ec4f..61791f8 100755 (executable)
@@ -28,10 +28,10 @@ static NSMutableSet *servsockets;
 -(void)stopConnection;
 -(void)setupRendezvousAdvertising;
 -(void)stopRendezvousAdvertising;
--(void)setupTimer;
--(void)stopTimer;
-+(void)globalTimerFunc:(NSTimer*)timer;
--(void)timerFunc:(NSTimer*)timer;
+-(void)setupThread;
+-(void)stopThread;
+-(void)newClient:(int)cfd;
+-(void)socketAcceptLoop:(id)data;
 @end
 
 @implementation ITInetServerSocket
@@ -50,6 +50,7 @@ static NSMutableSet *servsockets;
           clients = [[NSMutableSet alloc] init];
           service = nil;
           port = 0;
+          dieflag = 0;
           rndType = rndName = nil;
           timer = nil;
           }
@@ -65,6 +66,7 @@ static NSMutableSet *servsockets;
           clients = [[NSMutableSet alloc] init];
           service = nil;
           port = 0;
+          dieflag = 0;
           rndType = rndName = nil;
           timer = nil;
           }
@@ -147,19 +149,9 @@ static NSMutableSet *servsockets;
 -(short)lookupPortForServiceType:(NSString*)name
 {
     const char *_name = [name cString];
-    struct addrinfo hints,*res;
+    struct addrinfo *res;
     short p;
-
-    hints.ai_flags = AI_PASSIVE;
-    hints.ai_family = PF_INET;
-    hints.ai_socktype = SOCK_STREAM;
-    hints.ai_protocol = IPPROTO_TCP;
-    hints.ai_addrlen = 0;
-    hints.ai_canonname = NULL;
-    hints.ai_addr = NULL;
-    hints.ai_next = NULL;
-
-    getaddrinfo(NULL,_name,&hints,&res);
+    getaddrinfo(NULL,_name,NULL,&res);
     p = ntohs(((struct sockaddr_in *)res->ai_addr)->sin_port);
     freeaddrinfo(res);
     return p;
@@ -167,17 +159,19 @@ static NSMutableSet *servsockets;
 
 -(void)setupConnection
 {
-    struct sockaddr_in sa;
-
-    sockfd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
-    sa.sin_addr.s_addr = INADDR_ANY;
-    sa.sin_family = AF_INET;
-    sa.sin_port = htons(port);
-    bind(sockfd,(struct sockaddr *)&sa,sizeof(sa));
+    struct addrinfo hints, *ai;
+    hints.ai_flags = AI_PASSIVE;
+    hints.ai_family = PF_INET6;
+    hints.ai_socktype = SOCK_STREAM;
+    hints.ai_protocol = IPPROTO_TCP;
+    hints.ai_addrlen = 0;
+    hints.ai_canonname = hints.ai_addr = hints.ai_next = NULL;
+    getaddrinfo(NULL,[[[NSNumber numberWithShort:port] stringValue] cString],&hints,&ai);
+    bind(sockfd,ai->ai_addr,ai->ai_addrlen);
     listen(sockfd, SOMAXCONN);
-    fcntl(sockfd,F_SETFL,O_NONBLOCK);
+    freeaddrinfo(ai);
     [self setupRendezvousAdvertising];
-    [self setupTimer];
+    [self setupThread];
 }
 
 - (void)stopConnection
@@ -202,41 +196,40 @@ static NSMutableSet *servsockets;
     service = nil;
 }
 
-- (void)setupTimer
+- (void)setupThread
 {
-    if (!timer) timer = [NSTimer timerWithTimeInterval:0 target:self selector:@selector(timerFunc:) userInfo:nil repeats:YES];
-    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
+    NSPort *p1 = [NSPort port], *p2 = [NSPort port];
+    NSConnection *dcon = [[NSConnection alloc] initWithReceivePort:p1 sendPort:p2];
+    NSArray *par = [NSArray arrayWithObjects:p2,p1,nil];
+    [dcon setRootObject:self];
+    [NSThread detachNewThreadSelector:@selector(socketAcceptLoop:) toTarget:self withObject:par]; 
 }
 
-- (void)stopTimer
+- (void)stopThread
 {
-    [timer invalidate];
-    [timer release];
-    timer = nil;
+    dieflag = 1;
 }
 
-+ (void)globalTimerFunc:(NSTimer*)timer
+- (void)newClient:(int)cfd
 {
-    [servsockets makeObjectsPerformSelector:@selector(timerFunc)];
+    ITInetSocket *csocket = [[ITInetSocket alloc] initWithFD:cfd delegate:delegate];
+    [clients addObject:csocket];
 }
 
-- (void)timerFunc:(NSTimer*)timer
+- (void)socketAcceptLoop:(id)data
 {
-    if (sockfd != -1)
+    NSAutoreleasePool *ap = [[NSAutoreleasePool alloc] init];
+    NSArray *par = data;
+    NSConnection *dcon = [[NSConnection alloc] initWithReceivePort:[par objectAtIndex:0] sendPort:[par objectAtIndex:1]];
+    NSProxy *dp = [dcon rootProxy];
+    while ((sockfd != -1) && !dieflag)
           {
-          struct sockaddr_in csa;
-          int csalen;
           signed int cfd;
-          cfd = accept(sockfd,(struct sockaddr*)&csa,&csalen);
-          if (cfd == -1) {
-                 if (errno == EWOULDBLOCK) ;
-                 else {perror("Too bad I haven't implemented error checking yet");}
-          }
-          else {
-                 ITInetSocket *csocket = [[ITInetSocket alloc] initWithFD:cfd delegate:self];
-                 [clients addObject:csocket];
-                 [delegate newClientJoined:csocket];
-          }
+          cfd = accept(sockfd,NULL,NULL);
+          [(id)dp newClient:cfd];
           }
+    dieflag = 0;
+    [dcon release];
+    [ap release];
 }
 @end
\ No newline at end of file
index 3eb0000..3a09aab 100755 (executable)
  * @abstract Definitions for the ITInetSocket class
  */
 
-/*!
- * @constant ITInetMaxConnections
- * @abstract The maximum number of running ITInetSockets you can have.
- * @discussion The socket will error during a connection request if you are over the maximum.
- */
-
-enum {
-    ITInetMaxConnections = 128
-};
 
 /*!
  * @enum ITInetSocketState
@@ -70,7 +61,7 @@ typedef enum {
  * @discussion The delegate should check [sender readPipe] to get the data.
  * @param sender The socket that the messages came from.
  */
-- (void) dataReceived:(ITInetSocket *)sender;
+- (oneway void) dataReceived:(ITInetSocket *)sender;
 /*!
  * @method errorOccured:during:onSocket:
  * @abstract Alerts the delegate of an error condition.
@@ -79,14 +70,14 @@ typedef enum {
  * @param state What the socket was doing when the error occured.
  * @param sender The socket the error occured on.
  */
-- (void) errorOccured:(ITInetSocketError)err during:(ITInetSocketState)state onSocket:(ITInetSocket*)sender;
+- (oneway void) errorOccured:(ITInetSocketError)err during:(ITInetSocketState)state onSocket:(ITInetSocket*)sender;
 /*!
  * @method finishedConnecting:
  * @abstract Alerts the delegate of a successful connection attempt.
  * @discussion The delegate should send whatever initial data is required for the protocol (nickname for IRC, etc.)
  * @param sender The socket that established the connection.
  */
-- (void) finishedConnecting:(ITInetSocket *)sender;
+- (oneway void) finishedConnecting:(ITInetSocket *)sender;
 @end
 
 /*!
index af5d8a2..decfd43 100755 (executable)
                  a->ai_next = malloc(sizeof(struct addrinfo));
                  a = a->ai_next;
           }
+          ai_cur = ai;
+          [self realDoConnection];
           }
 }
 
 {
     NSLog(@"Got a disconnect");
     dieflag = 1;
-    do {} while (dieflag == 1);
 }
 
 -(void)retryConnection
 {
     NSLog(@"writePipe got something");
     actionflag = 1;
+    do {} while (actionflag == 1);
     NSLog(@"thread saw actionFlag");
 }
 @end
     struct addrinfo hints;
           int err;
           const char *portNam = [namedPort cString], *hostCStr = [host cString];
-
+          state = ITInetSocketConnecting;
           hints.ai_flags = 0;
           hints.ai_family = PF_UNSPEC;
           hints.ai_socktype = SOCK_STREAM;
     NSLog(@"Sending finishedConnecting");
     [(id)dp finishedConnecting:self];
 lstart:
-
+          state = ITInetSocketListening;
           while (!actionflag && !dieflag)
           {
-                 NSData *d;
                  readLen = recv(sockfd,buf,bufs,0);
+                 state = ITInetSocketReading;
                  if (readLen == -1) {[(id)dp errorOccured:ITInetConnectionDropped during:ITInetSocketReading onSocket:self];goto dieaction;}
                  if (readLen) {
                         NSLog(@"recv'd");
@@ -260,12 +262,13 @@ lstart:
                         ap = [[NSAutoreleasePool alloc] init];
                  }
           }
-
+          state = ITInetSocketListening;
     actionflag = 0;
 
     if (dieflag)
           {
 dieaction:
+          state = ITInetSocketDisconnected;
           perror("Awh");
           free(buf);
           shutdown(sockfd,2);
@@ -277,6 +280,7 @@ dieaction:
           }
 
     {
+          state = ITInetSocketWriting;
           NSLog(@"Emptying writePipe");
           NSData *d = [writePipe readAllData];
           write(sockfd,[d bytes],[d length]);