DO patch from Richard Frith-MacDonald <richard@brainstorm.co.uk>

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@2410 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Adam Fedor 1997-09-09 15:30:24 +00:00
parent 4d6732922c
commit 79c7545d62
9 changed files with 384 additions and 149 deletions

View file

@ -278,9 +278,10 @@ static int messages_received_count;
+ new
{
id newPort = [default_receive_port_class newForReceiving];
id newConn =
[NSConnection newForInPort:newPort outPort:nil ancestorConnection:nil];
id newPort = [[default_receive_port_class newForReceiving] autorelease];
id newConn = [NSConnection newForInPort:newPort
outPort:nil
ancestorConnection:nil];
return newConn;
}
@ -291,7 +292,7 @@ static int messages_received_count;
if (p == nil) {
return nil;
}
return [self rootProxyAtPort: p];
return [self rootProxyAtPort: [p autorelease]];
}
- (void) addRequestMode: (NSString*)mode
@ -308,14 +309,24 @@ static int messages_received_count;
if (debug_connection)
printf("deallocating 0x%x\n", (unsigned)self);
[self invalidate];
/* Remove rootObject from root_object_dictionary
if this is last connection */
if (![NSConnection connectionsCountWithInPort:receive_port])
[NSConnection setRootObject:nil forInPort:receive_port];
[NotificationDispatcher removeObserver: self];
/* Remove receive port from run loop. */
[self setRequestMode: nil];
[[NSRunLoop currentRunLoop] removePort: receive_port
forMode: NSConnectionReplyMode];
[request_modes release];
/* Finished with ports - releasing them may generate a notification */
[receive_port release];
[send_port release];
[request_modes release];
/* Don't need notifications any more - so remove self as observer. */
[NotificationDispatcher removeObserver: self];
[proxiesHashGate lock];
NSFreeMapTable (remote_proxies);
@ -339,9 +350,10 @@ static int messages_received_count;
- (id) init
{
id newPort = [default_receive_port_class newForReceiving];
id newConn =
[NSConnection newForInPort:newPort outPort:nil ancestorConnection:nil];
id newPort = [[default_receive_port_class newForReceiving] autorelease];
id newConn = [NSConnection newForInPort:newPort
outPort:nil
ancestorConnection:nil];
[self release];
return newConn;
}
@ -365,6 +377,12 @@ static int messages_received_count;
{
is_valid = 0;
/*
* We can't be the ancestor of anything if we are invalid.
*/
if (self == NSMapGet(receive_port_2_ancestor, receive_port))
NSMapRemove(receive_port_2_ancestor, receive_port);
/*
* If we have been invalidated, we don't need to retain proxies
* for local objects any more. In fact, we want to get rid of
@ -515,7 +533,7 @@ static int messages_received_count;
while ([request_modes count]>1) {
[self removeRequestMode:[request_modes objectAtIndex:1]];
}
if ([request_modes count] == 0) {
if (mode != nil && [request_modes count] == 0) {
[self addRequestMode:mode];
}
}
@ -667,7 +685,7 @@ static int messages_received_count;
id newPort;
id newConn;
newPort = [default_receive_port_class newForReceiving];
newPort = [[default_receive_port_class newForReceiving] autorelease];
newConn = [self newForInPort:newPort outPort:nil
ancestorConnection:nil];
[self setRootObject:anObj forInPort:newPort];
@ -687,8 +705,9 @@ static int messages_received_count;
id newConn;
newPort = [default_receive_port_class newForReceivingFromRegisteredName: n];
newConn = [self newForInPort:newPort outPort:nil
ancestorConnection:nil];
newConn = [self newForInPort:[newPort autorelease]
outPort:nil
ancestorConnection:nil];
[self setRootObject:anObj forInPort:newPort];
return newConn;
}
@ -706,10 +725,12 @@ static int messages_received_count;
+ (NSDistantObject*) rootProxyAtPort: (NSPort*)anOutPort
{
id newInPort = [default_receive_port_class newForReceiving];
return [self rootProxyAtPort: anOutPort withInPort: newInPort];
return [self rootProxyAtPort: anOutPort
withInPort: [newInPort autorelease]];
}
+ (NSDistantObject*) rootProxyAtPort: (NSPort*)anOutPort withInPort: (NSPort *)anInPort
+ (NSDistantObject*) rootProxyAtPort: (NSPort*)anOutPort
withInPort: (NSPort *)anInPort
{
NSConnection *newConn = [self newForInPort:anInPort
outPort:anOutPort
@ -809,10 +830,6 @@ static int messages_received_count;
if (!(ancestor = NSMapGet (receive_port_2_ancestor, ip)))
{
NSMapInsert (receive_port_2_ancestor, ip, newConn);
[[NSRunLoop currentRunLoop] addPort: (NSPort*)ip
forMode: NSDefaultRunLoopMode];
[[NSRunLoop currentRunLoop] addPort: (NSPort*)ip
forMode: NSConnectionReplyMode];
/* This will cause the connection with the registered name
to receive the -invokeWithObject: from the IN_PORT.
This ends up being the ancestor of future new NSConnections
@ -837,8 +854,16 @@ static int messages_received_count;
newConn->independant_queueing = NO;
newConn->reply_depth = 0;
newConn->delegate = nil;
/*
* Set up request modes array and make sure the receiving port is
* added to the run loop to get data.
*/
newConn->request_modes = [[NSMutableArray arrayWithObject:
NSDefaultRunLoopMode] retain];
[[NSRunLoop currentRunLoop] addPort: (NSPort*)ip
forMode: NSDefaultRunLoopMode];
[[NSRunLoop currentRunLoop] addPort: (NSPort*)ip
forMode: NSConnectionReplyMode];
/* Ssk the delegate for permission, (OpenStep-style and GNUstep-style). */
@ -967,6 +992,7 @@ static int messages_received_count;
int seq_num;
NSParameterAssert (is_valid);
[[self retain] autorelease];
op = [self newSendingRequestRmc];
seq_num = [op sequenceNumber];
@ -1018,6 +1044,11 @@ static int messages_received_count;
/* If we didn't get the reply packet yet, get it now. */
if (!ip)
{
if (!is_valid)
{
[NSException raise: NSGenericException
format: @"connection waiting for request was shut down"];
}
/* xxx Why do we get the reply packet in here, and not
just before calling dissect_method_return() below? */
ip = [self _getReceivedReplyRmcWithSequenceNumber:seq_num];
@ -1100,6 +1131,11 @@ static int messages_received_count;
if (op == nil)
{
BOOL is_exception = NO;
/* It is possible that our connection died while the method was
being called - in this case we mustn't try to send the result
back to the remote application! */
if (!is_valid)
return;
op = [self newSendingReplyRmcWithSequenceNumber:
reply_sequence_number];
[op encodeValueOfCType: @encode(BOOL)
@ -1152,13 +1188,16 @@ static int messages_received_count;
[op release];
/* Send the exception back to the client. */
op = [self newSendingReplyRmcWithSequenceNumber: reply_sequence_number];
[op encodeValueOfCType: @encode(BOOL)
at: &is_exception
withName: @"Exceptional reply flag"];
[op encodeBycopyObject: localException
withName: @"Exception object"];
[op dismiss];
if (is_valid)
{
op=[self newSendingReplyRmcWithSequenceNumber: reply_sequence_number];
[op encodeValueOfCType: @encode(BOOL)
at: &is_exception
withName: @"Exceptional reply flag"];
[op encodeBycopyObject: localException
withName: @"Exception object"];
[op dismiss];
}
}
NS_ENDHANDLER;
@ -1315,18 +1354,20 @@ static int messages_received_count;
- (void) _handleRmc: rmc
{
NSConnection* conn = [[rmc connection] retain];
switch ([rmc identifier])
{
case ROOTPROXY_REQUEST:
/* It won't take much time to handle this, so go ahead and service
it, even if we are waiting for a reply. */
[[rmc connection] _service_rootObject: rmc];
[conn _service_rootObject: rmc];
[rmc dismiss];
break;
case METHODTYPE_REQUEST:
/* It won't take much time to handle this, so go ahead and service
it, even if we are waiting for a reply. */
[[rmc connection] _service_typeForSelector: rmc];
[conn _service_typeForSelector: rmc];
[rmc dismiss];
break;
case METHOD_REQUEST:
@ -1343,15 +1384,17 @@ static int messages_received_count;
then we may still want to service it now if DELAY_DIALOG_INTERRUPTIONS
is false. */
if (reply_depth == 0
|| ([rmc connection] == self && independant_queueing == NO)
|| (conn == self && independant_queueing == NO)
|| !delay_dialog_interruptions)
{
[[rmc connection] _service_forwardForProxy: rmc];
[self retain];
[conn _service_forwardForProxy: rmc];
/* Service any requests that were queued while we
were waiting for replies.
xxx Is this the right place for this check? */
if (reply_depth == 0)
[self _handleQueuedRmcRequests];
[self release];
}
else
{
@ -1370,18 +1413,20 @@ static int messages_received_count;
break;
case CONNECTION_SHUTDOWN:
{
[[rmc connection] _service_shutdown: rmc forConnection: self];
[conn _service_shutdown: rmc forConnection: self];
break;
}
case PROXY_RELEASE:
{
[[rmc connection] _service_release: rmc forConnection: self];
[conn _service_release: rmc forConnection: self];
break;
}
default:
[conn release];
[NSException raise: NSGenericException
format: @"unrecognized NSPortCoder identifier"];
}
[conn release];
}
- (void) _handleQueuedRmcRequests
@ -1389,7 +1434,7 @@ static int messages_received_count;
id rmc;
[received_request_rmc_queue_gate lock];
while ((rmc = [received_request_rmc_queue dequeueObject]))
while (is_valid && (rmc = [received_request_rmc_queue dequeueObject]))
{
[received_request_rmc_queue_gate unlock];
[self _handleRmc: rmc];
@ -1561,34 +1606,44 @@ static int messages_received_count;
- (void) _release_targets: (unsigned int*)list count:(unsigned int)number
{
/*
* Tell the remote app that it can release its local objects
* for the targets in the specified list since we don't have
* proxies for them any more.
*/
if (receive_port && is_valid && number > 0) {
id op;
unsigned int i;
NS_DURING
{
/*
* Tell the remote app that it can release its local objects
* for the targets in the specified list since we don't have
* proxies for them any more.
*/
if (receive_port && is_valid && number > 0) {
id op;
unsigned int i;
op = [[self encodingClass]
newForWritingWithConnection: self
sequenceNumber: [self _newMsgNumber]
identifier: PROXY_RELEASE];
op = [[self encodingClass]
newForWritingWithConnection: self
sequenceNumber: [self _newMsgNumber]
identifier: PROXY_RELEASE];
[op encodeValueOfCType: @encode(typeof(number))
at: &number
withName: NULL];
for (i = 0; i < number; i++) {
unsigned int target = list[i];
[op encodeValueOfCType: @encode(typeof(target))
at: &target
[op encodeValueOfCType: @encode(typeof(number))
at: &number
withName: NULL];
}
[op dismiss];
for (i = 0; i < number; i++) {
unsigned int target = list[i];
[op encodeValueOfCType: @encode(typeof(target))
at: &target
withName: NULL];
}
[op dismiss];
}
}
NS_HANDLER
{
if (debug_connection)
fprintf (stderr, "failed to release targets - %s\n",
[[localException name] cStringNoCopy]);
}
NS_ENDHANDLER
}
- (void) removeProxy: (NSDistantObject*)aProxy
@ -1828,33 +1883,29 @@ static int messages_received_count;
/* Shutting down and deallocating. */
/* We register this method with NotificationDispatcher for when a port dies. */
/*
* We register this method for a notification when a port dies.
* NB. It is possible that the death of a port could be notified
* to us after we are invalidated - in which case we must ignore it.
*/
- (void) portIsInvalid: notification
{
id port = [notification object];
if (is_valid) {
id port = [notification object];
NSParameterAssert (is_valid);
if (debug_connection)
fprintf (stderr, "Received port invalidation notification for "
"connection 0x%x\n\t%s\n", (unsigned)self,
[[port description] cStringNoCopy]);
/* We shouldn't be getting any port invalidation notifications,
except from our own ports; this is how we registered ourselves
with the NotificationDispatcher in
+newForInPort:outPort:ancestorConnection. */
NSParameterAssert (port == receive_port || port == send_port);
if (debug_connection)
fprintf (stderr, "Received port invalidation notification for "
"connection 0x%x\n\t%s\n", (unsigned)self,
[[port description] cStringNoCopy]);
/* xxx This also needs to be done properly in cases where the
Connection invalidates itself. */
/* Remove ourselves from the receive_port_2_ancestor, if necessary. */
{
id ancestor;
if ([port isKindOfClass: [InPort class]]
&& (self == (ancestor = NSMapGet (receive_port_2_ancestor, port))))
NSMapRemove (receive_port_2_ancestor, port);
}
[self invalidate];
/* xxx Anything else? */
/* We shouldn't be getting any port invalidation notifications,
except from our own ports; this is how we registered ourselves
with the NotificationDispatcher in
+newForInPort:outPort:ancestorConnection. */
NSParameterAssert (port == receive_port || port == send_port);
[self invalidate];
}
}
@end

View file

@ -1,8 +1,8 @@
/* Implementation of abstract superclass port for use with Connection
Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: July 1994
Written by: Richard Frith-Macdonald <richard@brainstorm.co.uk>
Created: August 1997
This file is part of the GNUstep Base Library.
@ -23,6 +23,7 @@
#include <Foundation/NSString.h>
#include <Foundation/NSPort.h>
#include <Foundation/NSAutoreleasePool.h>
NSString* NSPortDidBecomeInvalidNotification
= @"NSPortDidBecomeInvalidNotification";
@ -91,6 +92,27 @@ NSString *NSPortTimeoutException
return nil;
}
- (void) release
{
if (is_valid && [self retainCount] == 1) {
NSAutoreleasePool *arp;
/*
* If the port is about to have a final release deallocate it
* we must invalidate it. Use a local autorelease pool when
* invalidating so that we know that anything refering to this
* port during the invalidation process is released immediately.
* Also - bracket with retain/release pair to prevent recursion.
*/
[super retain];
arp = [[NSAutoreleasePool alloc] init];
[self invalidate];
[arp release];
[super release];
}
[super release];
}
- (void) setDelegate: anObject
{
delegate = anObject;

View file

@ -34,6 +34,7 @@
#include <gnustep/base/CStream.h>
#include <gnustep/base/Port.h>
#include <gnustep/base/MemoryStream.h>
#include <Foundation/NSException.h>
#include <Foundation/DistributedObjects.h>
#include <assert.h>
@ -103,8 +104,19 @@ static BOOL debug_connected_coder = NO;
- (void) dismiss
{
id packet = [cstream stream];
[(OutPort*)[connection sendPort] sendPacket: packet
NS_DURING
{
[(OutPort*)[connection sendPort] sendPacket: packet
timeout: [connection requestTimeout]];
}
NS_HANDLER
{
if (debug_connected_coder)
fprintf(stderr, "dismiss 0x%x: #=%d i=%d write failed - %s\n",
(unsigned)self, sequence_number, identifier,
[[localException reason] cStringNoCopy]);
}
NS_ENDHANDLER
if (debug_connected_coder)
fprintf(stderr, "dismiss 0x%x: #=%d i=%d %d\n",
(unsigned)self, sequence_number, identifier,

View file

@ -115,12 +115,15 @@ static int debug_run_loop = 0;
id receiver;
RunLoopEventType type;
NSDate* limit;
unsigned count;
}
- (void) eventFor: (void*)info mode: (NSString*)mode;
- (void*) getData;
- (NSDate*) getLimit;
- (id) getReceiver;
- (RunLoopEventType) getType;
- (BOOL) decrement;
- (void) increment;
- initWithType: (RunLoopEventType)type
receiver: (id)anObj
data: (void*)data;
@ -135,11 +138,23 @@ static int debug_run_loop = 0;
- (void) dealloc
{
[self invalidate];
[limit release];
[receiver release];
[super dealloc];
}
- (BOOL) decrement
{
if (count > 0) {
count--;
if (count > 0) {
return YES;
}
}
return NO;
}
- (void) eventFor: (void*)info mode: (NSString*)mode
{
if ([self isValid] == NO) {
@ -184,6 +199,11 @@ static int debug_run_loop = 0;
return type;
}
- (void) increment
{
count++;
}
- initWithType: (RunLoopEventType)aType
receiver: (id)anObj
data: (void*)item
@ -202,6 +222,7 @@ static int debug_run_loop = 0;
[self setReceiver:anObj];
[self setData:item];
[self setLimit:nil];
count = 0;
}
return self;
}
@ -239,10 +260,11 @@ static int debug_run_loop = 0;
- (void) setReceiver: anObject
{
id obj = [anObject retain];
id obj = receiver;
[receiver release];
receiver = obj;
receiver = [anObject retain];
[obj release];
}
@end
@ -333,8 +355,15 @@ static int debug_run_loop = 0;
@interface NSRunLoop (Private)
- (void) _addWatcher: (RunLoopWatcher*) item forMode: (NSString*)mode;
- (void) _addWatcher: (RunLoopWatcher*)item
forMode: (NSString*)mode;
- (void) _checkPerformers;
- (RunLoopWatcher*) _getWatcher: (void*)data
type: (RunLoopEventType)type
forMode: (NSString*)mode;
- (void) _removeWatcher: (void*)data
type: (RunLoopEventType)type
forMode: (NSString*)mode;
@end
@ -344,14 +373,14 @@ static int debug_run_loop = 0;
limit-date order. */
- (void) _addWatcher: (RunLoopWatcher*) item forMode: (NSString*)mode
{
Array *watchers;
id obj;
NSDate* limit;
int count;
NSMutableArray *watchers;
id obj;
NSDate *limit;
int count;
watchers = NSMapGet (_mode_2_watchers, mode);
if (watchers == nil) {
watchers = [Array new];
watchers = [NSMutableArray new];
NSMapInsert (_mode_2_watchers, mode, watchers);
[watchers release];
count = 0;
@ -463,15 +492,26 @@ static int debug_run_loop = 0;
if (mode == nil)
mode = _current_mode;
/* Remove any existing handler for the specified descriptor. */
[self removeEvent: data type: type forMode: mode];
info = [self _getWatcher: data type: type forMode: mode];
/* Create new object to hold information. */
info = [[RunLoopWatcher alloc] initWithType: type
receiver: watcher
data: data];
[self _addWatcher:info forMode:mode];
[info release];
if (info && [info getReceiver] == watcher) {
/* Increment usage count for this watcher. */
[info increment];
}
else {
/* Remove any existing handler for another watcher. */
[self _removeWatcher: data type: type forMode: mode];
/* Create new object to hold information. */
info = [[RunLoopWatcher alloc] initWithType: type
receiver: watcher
data: data];
/* Add the object to the array for the mode and keep count. */
[self _addWatcher:info forMode:mode];
[info increment];
[info release]; /* Now held in array. */
}
}
- (void) addReadDescriptor: (int)fd
@ -498,38 +538,35 @@ static int debug_run_loop = 0;
- (void) removeEvent: (void*)data
type: (RunLoopEventType)type
forMode: (NSString*)mode
all: (BOOL)removeAll
{
Array* watchers;
if (mode == nil)
mode = _current_mode;
if (removeAll) {
[self _removeWatcher: data type: type forMode: mode];
}
else {
RunLoopWatcher *info;
if (mode == nil )
mode = _current_mode;
watchers = NSMapGet (_mode_2_watchers, mode);
if (watchers) {
int i;
for (i = [watchers count]; i > 0; i--) {
RunLoopWatcher* info;
info = (RunLoopWatcher*)[watchers objectAtIndex:(i-1)];
if ([info getType] == type && [info getData] == data) {
[info invalidate];
[watchers removeObject: info];
}
}
info = [self _getWatcher: data type: type forMode: mode];
if (info && [info decrement] == NO) {
[self _removeWatcher: data type: type forMode: mode];
}
}
}
- (void) removeReadDescriptor: (int)fd
forMode: (NSString*)mode
{
return [self removeEvent:(void*)fd type: ET_RDESC forMode:mode];
return [self removeEvent:(void*)fd type: ET_RDESC forMode:mode all:NO];
}
- (void) removeWriteDescriptor: (int)fd
forMode: (NSString*)mode
{
return [self removeEvent:(void*)fd type: ET_WDESC forMode:mode];
return [self removeEvent:(void*)fd type: ET_WDESC forMode:mode all:NO];
}
- (BOOL) runOnceBeforeDate: date
@ -646,7 +683,7 @@ static int debug_run_loop = 0;
Heap *timers;
NSTimer *min_timer = nil;
RunLoopWatcher *min_watcher = nil;
Array *watchers;
NSArray *watchers;
NSDate *when;
saved_mode = _current_mode;
@ -872,10 +909,62 @@ static int debug_run_loop = 0;
wfd_2_object = NSCreateMapTable (NSIntMapKeyCallBacks,
NSObjectMapValueCallBacks, 0);
- (RunLoopWatcher*) _getWatcher: (void*)data
type: (RunLoopEventType)type
forMode: (NSString*)mode
{
NSArray *watchers;
RunLoopWatcher *info;
int count;
if (mode == nil)
mode = _current_mode;
watchers = NSMapGet (_mode_2_watchers, mode);
if (watchers == nil) {
return nil;
}
for (count = 0; count < [watchers count]; count++) {
info = [watchers objectAtIndex: count];
if ([info getType] == type) {
if ([info getData] == data) {
return info;
}
}
}
return nil;
}
- (void) _removeWatcher: (void*)data
type: (RunLoopEventType)type
forMode: (NSString*)mode
{
NSMutableArray *watchers;
if (mode == nil )
mode = _current_mode;
watchers = NSMapGet (_mode_2_watchers, mode);
if (watchers) {
int i;
for (i = [watchers count]; i > 0; i--) {
RunLoopWatcher* info;
info = (RunLoopWatcher*)[watchers objectAtIndex:(i-1)];
if ([info getType] == type && [info getData] == data) {
[info invalidate];
[watchers removeObject: info];
}
}
}
}
/* Do the pre-listening set-up for the file descriptors of this mode. */
{
Array* watchers;
NSArray *watchers;
watchers = NSMapGet (_mode_2_watchers, mode);
if (watchers) {
@ -1117,7 +1206,7 @@ id NSDefaultRunLoopMode = @"NSDefaultRunLoopMode";
- (void) removePort: (NSPort*)port
forMode: (NSString*)mode
{
return [self removeEvent:(void*)port type: ET_RPORT forMode:mode];
return [self removeEvent:(void*)port type: ET_RPORT forMode:mode all:NO];
}
@end

View file

@ -699,7 +699,7 @@ static NSMapTable* port_number_2_port;
if ((p = (id) NSMapGet (port_number_2_port, (void*)((int)n))))
{
assert (p->is_valid);
return p;
return [p retain];
}
/* There isn't already a TcpInPort for this port number, so create
@ -878,6 +878,7 @@ static NSMapTable* port_number_2_port;
want to wait for one directly from a port, you can use this method. */
- newPacketReceivedBeforeDate: date
{
NSString* saved_mode = [NSRunLoop currentMode];
id saved_packet_invocation;
id packet = nil;
id handle_packet (id p)
@ -894,7 +895,7 @@ static NSMapTable* port_number_2_port;
/* Make sure we're in the run loop, and run it, waiting for the
incoming packet. */
[[NSRunLoop currentRunLoop] addPort: self
forMode: [NSRunLoop currentMode]];
forMode: saved_mode];
while ([NSRunLoop runOnceBeforeDate: date]
&& !packet)
;
@ -904,7 +905,7 @@ static NSMapTable* port_number_2_port;
this run loop. */
_packet_invocation = saved_packet_invocation;
[[NSRunLoop currentRunLoop] removePort: self
forMode: [NSRunLoop currentMode]];
forMode: saved_mode];
return packet;
}
@ -1347,7 +1348,7 @@ static NSMapTable *out_port_bag = NULL;
work because sin_zero's may differ. */
{
assert (p->is_valid);
return p;
return [p retain];
}
}
}
@ -1681,8 +1682,7 @@ static NSMapTable *out_port_bag = NULL;
- (void) dealloc
{
if (is_valid)
[self invalidate];
[self invalidate];
[super dealloc];
}

View file

@ -144,14 +144,16 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
[self ignoreReadDescriptor];
[self ignoreWriteDescriptor];
if (closeOnDealloc == YES)
if (descriptor != -1)
{
close(descriptor);
descriptor = -1;
if (closeOnDealloc == YES)
{
close(descriptor);
descriptor = -1;
}
else if (isNonBlocking != wasNonBlocking)
[self setNonBlocking:wasNonBlocking];
}
else if (isNonBlocking != wasNonBlocking)
[self setNonBlocking:wasNonBlocking];
[readInfo release];
[writeInfo release];
[super dealloc];
@ -531,9 +533,11 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
- (NSData*)availableData
{
char buf[NETBUF_SIZE];
NSMutableData* d = [NSMutableData dataWithCapacity:0];
NSMutableData* d;
int len;
[self checkRead];
d = [NSMutableData dataWithCapacity:0];
if (isStandardFile)
{
while ((len = read(descriptor, buf, sizeof(buf))) > 0)
@ -560,9 +564,11 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
- (NSData*)readDataToEndOfFile
{
char buf[NETBUF_SIZE];
NSMutableData* d = [NSMutableData dataWithCapacity:0];
NSMutableData* d;
int len;
[self checkRead];
d = [NSMutableData dataWithCapacity:0];
while ((len = read(descriptor, buf, sizeof(buf))) > 0)
{
[d appendBytes:buf length:len];
@ -578,9 +584,11 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
- (NSData*)readDataOfLength:(unsigned int)len
{
NSMutableData* d = [NSMutableData dataWithCapacity:len];
NSMutableData* d;
int pos;
[self checkRead];
d = [NSMutableData dataWithCapacity:len];
if ((pos = read(descriptor, [d mutableBytes], len)) < 0)
{
[NSException raise: NSFileHandleOperationException
@ -598,6 +606,7 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
unsigned int len = [item length];
unsigned int pos = 0;
[self checkWrite];
while (pos < len)
{
int toWrite = len - pos;
@ -678,7 +687,7 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
{
off_t result = -1;
if (isStandardFile)
if (isStandardFile && descriptor >= 0)
result = lseek(descriptor, 0, SEEK_CUR);
if (result < 0)
{
@ -693,7 +702,7 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
{
off_t result = -1;
if (isStandardFile)
if (isStandardFile && descriptor >= 0)
result = lseek(descriptor, 0, SEEK_END);
if (result < 0)
{
@ -708,7 +717,7 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
{
off_t result = -1;
if (isStandardFile)
if (isStandardFile && descriptor >= 0)
result = lseek(descriptor, (off_t)pos, SEEK_SET);
if (result < 0)
{
@ -739,6 +748,10 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
(void)close(descriptor);
descriptor = -1;
acceptOK = NO;
connectOK = NO;
readOK = NO;
writeOK = NO;
}
- (void)synchronizeFile
@ -749,7 +762,7 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
- (void)truncateFileAtOffset:(unsigned long long)pos
{
if (isStandardFile)
if (isStandardFile && descriptor >= 0)
(void)ftruncate(descriptor, pos);
[self seekToFileOffset:pos];
}
@ -855,13 +868,15 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
{
[l removeEvent: (void*)descriptor
type: ET_RDESC
forMode: [modes objectAtIndex:i]];
forMode: [modes objectAtIndex:i]
all: YES];
}
}
else
[l removeEvent: (void*)descriptor
type: ET_RDESC
forMode: NSDefaultRunLoopMode];
forMode: NSDefaultRunLoopMode
all: YES];
}
- (void)ignoreWriteDescriptor
@ -887,19 +902,25 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
{
[l removeEvent: (void*)descriptor
type: ET_WDESC
forMode: [modes objectAtIndex:i]];
forMode: [modes objectAtIndex:i]
all: YES];
}
}
else
[l removeEvent: (void*)descriptor
type: ET_WDESC
forMode: NSDefaultRunLoopMode];
forMode: NSDefaultRunLoopMode
all: YES];
}
- (void)watchReadDescriptorForModes:(NSArray*)modes;
{
NSRunLoop* l = [NSRunLoop currentRunLoop];
NSRunLoop* l;
if (descriptor < 0)
return;
l = [NSRunLoop currentRunLoop];
[self setNonBlocking:YES];
if (modes && [modes count])
{
@ -925,6 +946,9 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
- (void)watchWriteDescriptor
{
if (descriptor < 0)
return;
if ([writeInfo count] > 0)
{
NSMutableDictionary* info = [writeInfo objectAtIndex:0];
@ -1020,8 +1044,9 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
}
}
else if (type == ET_WDESC) {
NSMutableDictionary* info = [writeInfo objectAtIndex:0];
NSMutableDictionary* info;
info = [writeInfo objectAtIndex:0];
operation = [info objectForKey:NotificationKey];
if (operation == GSFileHandleWriteCompletionNotification) {
NSData* item;
@ -1073,6 +1098,9 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
{
int e;
if (descriptor < 0)
return;
if (isStandardFile)
return;