From aba3cfc464d0f6b1dda0e08cc6d70c0fac11a98c Mon Sep 17 00:00:00 2001 From: Richard Frith-MacDonald Date: Fri, 25 Feb 2000 13:56:20 +0000 Subject: [PATCH] Minor port/runloop fixes git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@6108 72102866-910b-0410-8b05-ffd578937521 --- ChangeLog | 7 +++ Headers/gnustep/base/NSPort.h | 4 +- Source/GSTcpPort.m | 84 ++++++++++++++++++++++++++++------- Source/NSPort.m | 5 ++- Source/NSRunLoop.m | 47 ++++++++++++-------- 5 files changed, 108 insertions(+), 39 deletions(-) diff --git a/ChangeLog b/ChangeLog index dd5292758..d8a90ce74 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +Fri Feb 25 12:56:00 2000 Richard Frith-Macdonald + + * Source/NSPort.m: provide default implementations for methods dealing + with adding connections to run loop. + * Source/NSRunLoop.m: Check to see if ports have been invalidated and + remove them from run loop if they have. + Thu Feb 24 21:05:00 2000 Richard Frith-Macdonald * Source/NSBundle.m: ([-initWithPath:]) added code suggested by diff --git a/Headers/gnustep/base/NSPort.h b/Headers/gnustep/base/NSPort.h index 1d4a92492..5bfce12df 100644 --- a/Headers/gnustep/base/NSPort.h +++ b/Headers/gnustep/base/NSPort.h @@ -36,8 +36,8 @@ extern NSString *NSPortTimeoutException; /* OPENSTEP */ @interface NSPort : NSObject { - BOOL _is_valid; - id _delegate; + BOOL _is_valid; + id _delegate; } + (NSPort*) port; diff --git a/Source/GSTcpPort.m b/Source/GSTcpPort.m index 425c9b7ca..3decac137 100644 --- a/Source/GSTcpPort.m +++ b/Source/GSTcpPort.m @@ -171,14 +171,14 @@ typedef enum { forMode: (NSString*)mode; @end -@interface GSTcpPort : NSPort +@interface GSTcpPort : NSPort { NSRecursiveLock *myLock; NSHost *host; /* OpenStep host for this port. */ NSString *address; /* Forced internet address. */ gsu16 portNum; /* TCP port in host byte order. */ int listener; /* Descriptor to listen on. */ - NSMapTable *handles; /* Handles indexed by port. */ + NSMapTable *handles; /* Handles indexed by socket. */ } + (GSTcpPort*) existingPortWithNumber: (gsu16)number @@ -187,14 +187,21 @@ typedef enum { onHost: (NSHost*)host forceAddress: (NSString*)addr; -- (void) addHandle: (GSTcpHandle*)handle forPort: (GSTcpPort*)other; +- (void) addHandle: (GSTcpHandle*)handle; - (NSString*) address; - (void) getFds: (int*)fds count: (int*)count; - (GSTcpHandle*) handleForPort: (GSTcpPort*)recvPort beforeDate: (NSDate*)when; - (void) handlePortMessage: (NSPortMessage*)m; - (NSHost*) host; - (gsu16) portNumber; +- (void) receivedEvent: (void*)data + type: (RunLoopEventType)type + extra: (void*)extra + forMode: (NSString*)mode; - (void) removeHandle: (GSTcpHandle*)h; +- (NSDate*) timedOutEvent: (void*)data + type: (RunLoopEventType)type + forMode: (NSString*)mode; @end @@ -336,10 +343,13 @@ static NSMapTable *tcpHandleTable = 0; handle->desc = d; handle->wMsgs = [NSMutableArray new]; NSMapInsert(tcpHandleTable, (void*)(gsaddr)d, (void*)handle); - RELEASE(handle); + } + else + { + RETAIN(handle); } [tcpHandleLock unlock]; - return handle; + return AUTORELEASE(handle); } - (void) close @@ -565,9 +575,13 @@ static NSMapTable *tcpHandleTable = 0; res = read(desc, bytes + rLength, want - rLength); if (res <= 0) { - NSLog(@"read attempt failed - %s", strerror(errno)); - [self invalidate]; - return; + if (res == 0 || errno != EINTR) + { + NSLog(@"read attempt failed - %s", strerror(errno)); + [self invalidate]; + return; + } + res = 0; /* Interrupted - continue */ } rLength += res; if (rLength == want) @@ -660,8 +674,8 @@ static NSMapTable *tcpHandleTable = 0; */ state = GS_H_CONNECTED; [self setSendPort: p]; - [[self recvPort] addHandle: self forPort: p]; - [p addHandle: self forPort: [self recvPort]]; + [[self recvPort] addHandle: self]; + [p addHandle: self]; } else { @@ -735,7 +749,12 @@ static NSMapTable *tcpHandleTable = 0; res = write(desc, b + wLength, l - wLength); if (res <= 0) { - NSLog(@"write attempt failed - %s", strerror(errno)); + if (res == 0 || errno != EINTR) + { + NSLog(@"write attempt failed - %s", strerror(errno)); + [self invalidate]; + return; + } } else { @@ -952,7 +971,7 @@ static NSMapTable *tcpPortMap = 0; port->host = RETAIN(aHost); port->address = [addr copy]; port->handles = NSCreateMapTable(NSIntMapKeyCallBacks, - NSNonRetainedObjectMapValueCallBacks, 0); + NSObjectMapValueCallBacks, 0); port->myLock = [NSRecursiveLock new]; if ([thisHost isEqual: aHost] == YES) @@ -1086,10 +1105,10 @@ static NSMapTable *tcpPortMap = 0; return port; } -- (void) addHandle: (GSTcpHandle*)handle forPort: (GSTcpPort*)other +- (void) addHandle: (GSTcpHandle*)handle { [myLock lock]; - NSMapInsert(handles, (void*)handle, (void*)other); + NSMapInsert(handles, (void*)(gsaddr)[handle descriptor], (void*)handle); [myLock unlock]; } @@ -1191,8 +1210,8 @@ static NSMapTable *tcpPortMap = 0; { [handle setSendPort: self]; [handle setRecvPort: recvPort]; - NSMapInsert(handles, (void*)handle, (void*)recvPort); - NSMapInsert(recvPort->handles, (void*)handle, (void*)self); + [recvPort addHandle: handle]; + NSMapInsert(handles, (void*)(gsaddr)sock, (void*)handle); } } [myLock unlock]; @@ -1305,6 +1324,32 @@ static NSMapTable *tcpPortMap = 0; return portNum; } +- (void) receivedEvent: (void*)data + type: (RunLoopEventType)type + extra: (void*)extra + forMode: (NSString*)mode +{ + int desc = (int)(gsaddr)extra; + + if (desc == listener) + { + } + else + { + GSTcpHandle *handle; + + handle = [GSTcpHandle handleWithDescriptor: desc]; + if (handle == nil) + { + NSLog(@"No handle for event on descriptor %d", desc); + } + else + { + [handle receivedEvent: data type: type extra: extra forMode: mode]; + } + } +} + /* * This is called when a tcp/ip socket connection is broken. We remove the * connection handle from this port and, if this was the last handle to a @@ -1443,5 +1488,12 @@ static NSMapTable *tcpPortMap = 0; msgId: GS_CONNECTION_MSG]; } +- (NSDate*) timedOutEvent: (void*)data + type: (RunLoopEventType)type + forMode: (NSString*)mode +{ + return nil; +} + @end diff --git a/Source/NSPort.m b/Source/NSPort.m index 33f41d825..94a971449 100644 --- a/Source/NSPort.m +++ b/Source/NSPort.m @@ -27,6 +27,7 @@ #include #include #include +#include #include NSString* NSPortDidBecomeInvalidNotification @@ -137,14 +138,14 @@ NSString *NSPortTimeoutException toRunLoop: (NSRunLoop*)aLoop forMode: (NSString*)aMode { - [self subclassResponsibility: _cmd]; + [aLoop addPort: self forMode: aMode]; } - (void) removeConnection: (NSConnection*)aConnection fromRunLoop: (NSRunLoop*)aLoop forMode: (NSString*)aMode { - [self subclassResponsibility: _cmd]; + [aLoop removePort: self forMode: aMode]; } - (unsigned) reservedSpaceLength diff --git a/Source/NSRunLoop.m b/Source/NSRunLoop.m index 80fc61497..fac57abaa 100644 --- a/Source/NSRunLoop.m +++ b/Source/NSRunLoop.m @@ -1119,26 +1119,35 @@ const NSMapTableValueCallBacks ArrayMapValueCallBacks = break; case ET_RPORT: - { - id port = info->receiver; - int port_fd_count = 128; // xxx #define this constant - int port_fd_array[port_fd_count]; + if ([info->receiver isValid] == NO) + { + /* + * We must remove an invalidated port. + */ + info->_invalidated = YES; + GSIArrayRemoveItemAtIndex(watchers, i); + } + else + { + id port = info->receiver; + int port_fd_count = 128; // xxx #define this constant + int port_fd_array[port_fd_count]; - if ([port respondsTo: @selector(getFds:count:)]) - [port getFds: port_fd_array count: &port_fd_count]; - if (debug_run_loop) - printf("\tNSRunLoop listening to %d sockets\n", - port_fd_count); + if ([port respondsTo: @selector(getFds:count:)]) + [port getFds: port_fd_array count: &port_fd_count]; + if (debug_run_loop) + printf("\tNSRunLoop listening to %d sockets\n", + port_fd_count); - while (port_fd_count--) - { - FD_SET (port_fd_array[port_fd_count], &fds); - NSMapInsert(_rfdMap, - (void*)port_fd_array[port_fd_count], - info); - num_inputs++; - } - } + while (port_fd_count--) + { + FD_SET (port_fd_array[port_fd_count], &fds); + NSMapInsert(_rfdMap, + (void*)port_fd_array[port_fd_count], + info); + num_inputs++; + } + } break; } } @@ -1249,7 +1258,7 @@ const NSMapTableValueCallBacks ArrayMapValueCallBacks = eventSel, watcher->data, watcher->type, (void*)(gsaddr)fd_index, _current_mode); } - else if (watcher->type == ET_RDESC || watcher->type == ET_RPORT) + else if (watcher->type == ET_RDESC) { [watcher->receiver readyForReadingOnFileDescriptor: (int)(gsaddr)fd_index];