Minor port/runloop fixes

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@6108 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
richard 2000-02-25 13:56:20 +00:00
parent aa91b258f5
commit a573fbc08f
5 changed files with 108 additions and 39 deletions

View file

@ -1,3 +1,10 @@
Fri Feb 25 12:56:00 2000 Richard Frith-Macdonald <richard@brainstorm.co.uk>
* 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 <richard@brainstorm.co.uk> Thu Feb 24 21:05:00 2000 Richard Frith-Macdonald <richard@brainstorm.co.uk>
* Source/NSBundle.m: ([-initWithPath:]) added code suggested by * Source/NSBundle.m: ([-initWithPath:]) added code suggested by

View file

@ -36,8 +36,8 @@ extern NSString *NSPortTimeoutException; /* OPENSTEP */
@interface NSPort : NSObject <NSCoding, NSCopying> @interface NSPort : NSObject <NSCoding, NSCopying>
{ {
BOOL _is_valid; BOOL _is_valid;
id _delegate; id _delegate;
} }
+ (NSPort*) port; + (NSPort*) port;

View file

@ -171,14 +171,14 @@ typedef enum {
forMode: (NSString*)mode; forMode: (NSString*)mode;
@end @end
@interface GSTcpPort : NSPort <GCFinalization> @interface GSTcpPort : NSPort <GCFinalization, RunLoopEvents>
{ {
NSRecursiveLock *myLock; NSRecursiveLock *myLock;
NSHost *host; /* OpenStep host for this port. */ NSHost *host; /* OpenStep host for this port. */
NSString *address; /* Forced internet address. */ NSString *address; /* Forced internet address. */
gsu16 portNum; /* TCP port in host byte order. */ gsu16 portNum; /* TCP port in host byte order. */
int listener; /* Descriptor to listen on. */ int listener; /* Descriptor to listen on. */
NSMapTable *handles; /* Handles indexed by port. */ NSMapTable *handles; /* Handles indexed by socket. */
} }
+ (GSTcpPort*) existingPortWithNumber: (gsu16)number + (GSTcpPort*) existingPortWithNumber: (gsu16)number
@ -187,14 +187,21 @@ typedef enum {
onHost: (NSHost*)host onHost: (NSHost*)host
forceAddress: (NSString*)addr; forceAddress: (NSString*)addr;
- (void) addHandle: (GSTcpHandle*)handle forPort: (GSTcpPort*)other; - (void) addHandle: (GSTcpHandle*)handle;
- (NSString*) address; - (NSString*) address;
- (void) getFds: (int*)fds count: (int*)count; - (void) getFds: (int*)fds count: (int*)count;
- (GSTcpHandle*) handleForPort: (GSTcpPort*)recvPort beforeDate: (NSDate*)when; - (GSTcpHandle*) handleForPort: (GSTcpPort*)recvPort beforeDate: (NSDate*)when;
- (void) handlePortMessage: (NSPortMessage*)m; - (void) handlePortMessage: (NSPortMessage*)m;
- (NSHost*) host; - (NSHost*) host;
- (gsu16) portNumber; - (gsu16) portNumber;
- (void) receivedEvent: (void*)data
type: (RunLoopEventType)type
extra: (void*)extra
forMode: (NSString*)mode;
- (void) removeHandle: (GSTcpHandle*)h; - (void) removeHandle: (GSTcpHandle*)h;
- (NSDate*) timedOutEvent: (void*)data
type: (RunLoopEventType)type
forMode: (NSString*)mode;
@end @end
@ -336,10 +343,13 @@ static NSMapTable *tcpHandleTable = 0;
handle->desc = d; handle->desc = d;
handle->wMsgs = [NSMutableArray new]; handle->wMsgs = [NSMutableArray new];
NSMapInsert(tcpHandleTable, (void*)(gsaddr)d, (void*)handle); NSMapInsert(tcpHandleTable, (void*)(gsaddr)d, (void*)handle);
RELEASE(handle); }
else
{
RETAIN(handle);
} }
[tcpHandleLock unlock]; [tcpHandleLock unlock];
return handle; return AUTORELEASE(handle);
} }
- (void) close - (void) close
@ -565,9 +575,13 @@ static NSMapTable *tcpHandleTable = 0;
res = read(desc, bytes + rLength, want - rLength); res = read(desc, bytes + rLength, want - rLength);
if (res <= 0) if (res <= 0)
{ {
NSLog(@"read attempt failed - %s", strerror(errno)); if (res == 0 || errno != EINTR)
[self invalidate]; {
return; NSLog(@"read attempt failed - %s", strerror(errno));
[self invalidate];
return;
}
res = 0; /* Interrupted - continue */
} }
rLength += res; rLength += res;
if (rLength == want) if (rLength == want)
@ -660,8 +674,8 @@ static NSMapTable *tcpHandleTable = 0;
*/ */
state = GS_H_CONNECTED; state = GS_H_CONNECTED;
[self setSendPort: p]; [self setSendPort: p];
[[self recvPort] addHandle: self forPort: p]; [[self recvPort] addHandle: self];
[p addHandle: self forPort: [self recvPort]]; [p addHandle: self];
} }
else else
{ {
@ -735,7 +749,12 @@ static NSMapTable *tcpHandleTable = 0;
res = write(desc, b + wLength, l - wLength); res = write(desc, b + wLength, l - wLength);
if (res <= 0) 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 else
{ {
@ -952,7 +971,7 @@ static NSMapTable *tcpPortMap = 0;
port->host = RETAIN(aHost); port->host = RETAIN(aHost);
port->address = [addr copy]; port->address = [addr copy];
port->handles = NSCreateMapTable(NSIntMapKeyCallBacks, port->handles = NSCreateMapTable(NSIntMapKeyCallBacks,
NSNonRetainedObjectMapValueCallBacks, 0); NSObjectMapValueCallBacks, 0);
port->myLock = [NSRecursiveLock new]; port->myLock = [NSRecursiveLock new];
if ([thisHost isEqual: aHost] == YES) if ([thisHost isEqual: aHost] == YES)
@ -1086,10 +1105,10 @@ static NSMapTable *tcpPortMap = 0;
return port; return port;
} }
- (void) addHandle: (GSTcpHandle*)handle forPort: (GSTcpPort*)other - (void) addHandle: (GSTcpHandle*)handle
{ {
[myLock lock]; [myLock lock];
NSMapInsert(handles, (void*)handle, (void*)other); NSMapInsert(handles, (void*)(gsaddr)[handle descriptor], (void*)handle);
[myLock unlock]; [myLock unlock];
} }
@ -1191,8 +1210,8 @@ static NSMapTable *tcpPortMap = 0;
{ {
[handle setSendPort: self]; [handle setSendPort: self];
[handle setRecvPort: recvPort]; [handle setRecvPort: recvPort];
NSMapInsert(handles, (void*)handle, (void*)recvPort); [recvPort addHandle: handle];
NSMapInsert(recvPort->handles, (void*)handle, (void*)self); NSMapInsert(handles, (void*)(gsaddr)sock, (void*)handle);
} }
} }
[myLock unlock]; [myLock unlock];
@ -1305,6 +1324,32 @@ static NSMapTable *tcpPortMap = 0;
return portNum; 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 * 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 * 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]; msgId: GS_CONNECTION_MSG];
} }
- (NSDate*) timedOutEvent: (void*)data
type: (RunLoopEventType)type
forMode: (NSString*)mode
{
return nil;
}
@end @end

View file

@ -27,6 +27,7 @@
#include <Foundation/NSNotificationQueue.h> #include <Foundation/NSNotificationQueue.h>
#include <Foundation/NSPort.h> #include <Foundation/NSPort.h>
#include <Foundation/NSPortNameServer.h> #include <Foundation/NSPortNameServer.h>
#include <Foundation/NSRunLoop.h>
#include <Foundation/NSAutoreleasePool.h> #include <Foundation/NSAutoreleasePool.h>
NSString* NSPortDidBecomeInvalidNotification NSString* NSPortDidBecomeInvalidNotification
@ -137,14 +138,14 @@ NSString *NSPortTimeoutException
toRunLoop: (NSRunLoop*)aLoop toRunLoop: (NSRunLoop*)aLoop
forMode: (NSString*)aMode forMode: (NSString*)aMode
{ {
[self subclassResponsibility: _cmd]; [aLoop addPort: self forMode: aMode];
} }
- (void) removeConnection: (NSConnection*)aConnection - (void) removeConnection: (NSConnection*)aConnection
fromRunLoop: (NSRunLoop*)aLoop fromRunLoop: (NSRunLoop*)aLoop
forMode: (NSString*)aMode forMode: (NSString*)aMode
{ {
[self subclassResponsibility: _cmd]; [aLoop removePort: self forMode: aMode];
} }
- (unsigned) reservedSpaceLength - (unsigned) reservedSpaceLength

View file

@ -1119,26 +1119,35 @@ const NSMapTableValueCallBacks ArrayMapValueCallBacks =
break; break;
case ET_RPORT: case ET_RPORT:
{ if ([info->receiver isValid] == NO)
id port = info->receiver; {
int port_fd_count = 128; // xxx #define this constant /*
int port_fd_array[port_fd_count]; * 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:)]) if ([port respondsTo: @selector(getFds:count:)])
[port getFds: port_fd_array count: &port_fd_count]; [port getFds: port_fd_array count: &port_fd_count];
if (debug_run_loop) if (debug_run_loop)
printf("\tNSRunLoop listening to %d sockets\n", printf("\tNSRunLoop listening to %d sockets\n",
port_fd_count); port_fd_count);
while (port_fd_count--) while (port_fd_count--)
{ {
FD_SET (port_fd_array[port_fd_count], &fds); FD_SET (port_fd_array[port_fd_count], &fds);
NSMapInsert(_rfdMap, NSMapInsert(_rfdMap,
(void*)port_fd_array[port_fd_count], (void*)port_fd_array[port_fd_count],
info); info);
num_inputs++; num_inputs++;
} }
} }
break; break;
} }
} }
@ -1249,7 +1258,7 @@ const NSMapTableValueCallBacks ArrayMapValueCallBacks =
eventSel, watcher->data, watcher->type, eventSel, watcher->data, watcher->type,
(void*)(gsaddr)fd_index, _current_mode); (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: [watcher->receiver readyForReadingOnFileDescriptor:
(int)(gsaddr)fd_index]; (int)(gsaddr)fd_index];