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 Frith-MacDonald 2000-02-25 13:56:20 +00:00
parent 11c72e96e9
commit aba3cfc464
5 changed files with 108 additions and 39 deletions

View file

@ -171,14 +171,14 @@ typedef enum {
forMode: (NSString*)mode;
@end
@interface GSTcpPort : NSPort <GCFinalization>
@interface GSTcpPort : NSPort <GCFinalization, RunLoopEvents>
{
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

View file

@ -27,6 +27,7 @@
#include <Foundation/NSNotificationQueue.h>
#include <Foundation/NSPort.h>
#include <Foundation/NSPortNameServer.h>
#include <Foundation/NSRunLoop.h>
#include <Foundation/NSAutoreleasePool.h>
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

View file

@ -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];