mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-26 18:21:04 +00:00
Added registerName: method to NSConnection with associated changes
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@5923 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
78616c9359
commit
1629c565b9
6 changed files with 379 additions and 259 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
Fri Feb 4 17:20:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||||
|
|
||||||
|
* Source/NSPortNameServer.m: New methods for use by NSConnection
|
||||||
|
* Foundation/NSPortNameServer.h: ditto
|
||||||
|
* Source/NSConnection.m: Tidied a little and added ([-registerName:])
|
||||||
|
* Source/NSConnection.h: ditto
|
||||||
|
|
||||||
Sun Jan 16 9:10:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
Sun Jan 16 9:10:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||||
|
|
||||||
Moved objc-load.c to objc-load.m and filnd-exec.c to find-exec.m
|
Moved objc-load.c to objc-load.m and filnd-exec.c to find-exec.m
|
||||||
|
|
|
@ -95,6 +95,7 @@ extern NSString *NSConnectionProxyCount; /* Objects received */
|
||||||
- (BOOL) independentConversationQueueing;
|
- (BOOL) independentConversationQueueing;
|
||||||
- (void) invalidate;
|
- (void) invalidate;
|
||||||
- (BOOL) isValid;
|
- (BOOL) isValid;
|
||||||
|
- (BOOL) registerName: (NSString*)name;
|
||||||
- (NSArray *) remoteObjects;
|
- (NSArray *) remoteObjects;
|
||||||
- (void) removeRequestMode: (NSString*)mode;
|
- (void) removeRequestMode: (NSString*)mode;
|
||||||
- (void) removeRunLoop: (NSRunLoop *)runloop;
|
- (void) removeRunLoop: (NSRunLoop *)runloop;
|
||||||
|
|
|
@ -44,7 +44,9 @@
|
||||||
|
|
||||||
#ifndef NO_GNUSTEP
|
#ifndef NO_GNUSTEP
|
||||||
@interface NSPortNameServer (GNUstep)
|
@interface NSPortNameServer (GNUstep)
|
||||||
|
- (NSArray*) namesForPort: (NSPort*)port; /* return all names for port */
|
||||||
- (void) removePort: (NSPort*)port; /* remove all names for port */
|
- (void) removePort: (NSPort*)port; /* remove all names for port */
|
||||||
|
- (void) removePort: (NSPort*)port forName: (NSString*)name;
|
||||||
@end
|
@end
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
#include <Foundation/NSThread.h>
|
#include <Foundation/NSThread.h>
|
||||||
#include <Foundation/NSPort.h>
|
#include <Foundation/NSPort.h>
|
||||||
#include <Foundation/NSPortMessage.h>
|
#include <Foundation/NSPortMessage.h>
|
||||||
|
#include <Foundation/NSPortNameServer.h>
|
||||||
#include <Foundation/NSNotification.h>
|
#include <Foundation/NSNotification.h>
|
||||||
|
|
||||||
NSString* NSConnectionReplyMode = @"NSConnectionReplyMode";
|
NSString* NSConnectionReplyMode = @"NSConnectionReplyMode";
|
||||||
|
@ -264,13 +265,14 @@ static int messages_received_count;
|
||||||
+ (NSConnection*) connectionWithRegisteredName: (NSString*)n
|
+ (NSConnection*) connectionWithRegisteredName: (NSString*)n
|
||||||
host: (NSString*)h
|
host: (NSString*)h
|
||||||
{
|
{
|
||||||
NSDistantObject *proxy;
|
NSDistantObject *proxy;
|
||||||
|
|
||||||
proxy = [self rootProxyForConnectionWithRegisteredName: n host: h];
|
proxy = [self rootProxyForConnectionWithRegisteredName: n host: h];
|
||||||
if (proxy) {
|
if (proxy != nil)
|
||||||
return [proxy connectionForProxy];
|
{
|
||||||
|
return [proxy connectionForProxy];
|
||||||
}
|
}
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -287,36 +289,38 @@ static int messages_received_count;
|
||||||
|
|
||||||
d = GSCurrentThreadDictionary();
|
d = GSCurrentThreadDictionary();
|
||||||
c = (NSConnection*)[d objectForKey: tkey];
|
c = (NSConnection*)[d objectForKey: tkey];
|
||||||
if (c != nil && [c isValid] == NO) {
|
if (c != nil && [c isValid] == NO)
|
||||||
/*
|
{
|
||||||
* If the default connection for this thread has been invalidated -
|
/*
|
||||||
* release it and create a new one.
|
* If the default connection for this thread has been invalidated -
|
||||||
*/
|
* release it and create a new one.
|
||||||
[d removeObjectForKey: tkey];
|
*/
|
||||||
c = nil;
|
[d removeObjectForKey: tkey];
|
||||||
}
|
c = nil;
|
||||||
if (c == nil) {
|
}
|
||||||
c = [NSConnection new];
|
if (c == nil)
|
||||||
[d setObject: c forKey: tkey];
|
{
|
||||||
RELEASE(c);
|
c = [NSConnection new];
|
||||||
}
|
[d setObject: c forKey: tkey];
|
||||||
|
RELEASE(c);
|
||||||
|
}
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (void) initialize
|
+ (void) initialize
|
||||||
{
|
{
|
||||||
connection_table =
|
connection_table =
|
||||||
NSCreateHashTable (NSNonRetainedObjectHashCallBacks, 0);
|
NSCreateHashTable(NSNonRetainedObjectHashCallBacks, 0);
|
||||||
connection_table_gate = [NSLock new];
|
connection_table_gate = [NSLock new];
|
||||||
/* xxx When NSHashTable's are working, change this. */
|
/* xxx When NSHashTable's are working, change this. */
|
||||||
all_connections_local_objects =
|
all_connections_local_objects =
|
||||||
NSCreateMapTable (NSNonOwnedPointerMapKeyCallBacks,
|
NSCreateMapTable(NSNonOwnedPointerMapKeyCallBacks,
|
||||||
NSObjectMapValueCallBacks, 0);
|
NSObjectMapValueCallBacks, 0);
|
||||||
all_connections_local_targets =
|
all_connections_local_targets =
|
||||||
NSCreateMapTable (NSIntMapKeyCallBacks,
|
NSCreateMapTable(NSIntMapKeyCallBacks,
|
||||||
NSNonOwnedPointerMapValueCallBacks, 0);
|
NSNonOwnedPointerMapValueCallBacks, 0);
|
||||||
all_connections_local_cached =
|
all_connections_local_cached =
|
||||||
NSCreateMapTable (NSIntMapKeyCallBacks,
|
NSCreateMapTable(NSIntMapKeyCallBacks,
|
||||||
NSObjectMapValueCallBacks, 0);
|
NSObjectMapValueCallBacks, 0);
|
||||||
received_request_rmc_queue = [[NSMutableArray alloc] initWithCapacity: 32];
|
received_request_rmc_queue = [[NSMutableArray alloc] initWithCapacity: 32];
|
||||||
received_request_rmc_queue_gate = [NSLock new];
|
received_request_rmc_queue_gate = [NSLock new];
|
||||||
|
@ -337,16 +341,18 @@ static int messages_received_count;
|
||||||
default_request_timeout = CONNECTION_DEFAULT_TIMEOUT;
|
default_request_timeout = CONNECTION_DEFAULT_TIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ new
|
+ (id) new
|
||||||
{
|
{
|
||||||
id newPort = [[default_receive_port_class newForReceiving] autorelease];
|
NSPort *newPort;
|
||||||
id newConn = [NSConnection newForInPort: newPort
|
NSConnection *newConn;
|
||||||
outPort: nil
|
|
||||||
ancestorConnection: nil];
|
newConn = [self alloc];
|
||||||
|
newConn = [newConn initWithReceivePort: newPort sendPort: nil];
|
||||||
|
RELEASE(newPort);
|
||||||
return newConn;
|
return newConn;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (id)currentConversation
|
+ (id) currentConversation
|
||||||
{
|
{
|
||||||
[self notImplemented: _cmd];
|
[self notImplemented: _cmd];
|
||||||
return self;
|
return self;
|
||||||
|
@ -355,38 +361,43 @@ static int messages_received_count;
|
||||||
+ (NSDistantObject*) rootProxyForConnectionWithRegisteredName: (NSString*)n
|
+ (NSDistantObject*) rootProxyForConnectionWithRegisteredName: (NSString*)n
|
||||||
host: (NSString*)h
|
host: (NSString*)h
|
||||||
{
|
{
|
||||||
id p = [default_send_port_class newForSendingToRegisteredName: n onHost: h];
|
id p = [default_send_port_class newForSendingToRegisteredName: n onHost: h];
|
||||||
if (p == nil) {
|
if (p == nil)
|
||||||
return nil;
|
{
|
||||||
|
return nil;
|
||||||
}
|
}
|
||||||
return [self rootProxyAtPort: [p autorelease]];
|
return [self rootProxyAtPort: [p autorelease]];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (void) _timeout: (NSTimer*)t
|
+ (void) _timeout: (NSTimer*)t
|
||||||
{
|
{
|
||||||
NSArray *cached_locals;
|
NSArray *cached_locals;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
cached_locals = NSAllMapTableValues(all_connections_local_cached);
|
cached_locals = NSAllMapTableValues(all_connections_local_cached);
|
||||||
for (i = [cached_locals count]; i > 0; i--) {
|
for (i = [cached_locals count]; i > 0; i--)
|
||||||
CachedLocalObject *item = [cached_locals objectAtIndex: i-1];
|
{
|
||||||
|
CachedLocalObject *item = [cached_locals objectAtIndex: i-1];
|
||||||
|
|
||||||
if ([item countdown] == NO) {
|
if ([item countdown] == NO)
|
||||||
GSLocalCounter *counter = [item obj];
|
{
|
||||||
NSMapRemove(all_connections_local_cached, (void*)counter->target);
|
GSLocalCounter *counter = [item obj];
|
||||||
|
NSMapRemove(all_connections_local_cached, (void*)counter->target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ([cached_locals count] == 0) {
|
if ([cached_locals count] == 0)
|
||||||
[t invalidate];
|
{
|
||||||
timer = nil;
|
[t invalidate];
|
||||||
|
timer = nil;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) addRequestMode: (NSString*)mode
|
- (void) addRequestMode: (NSString*)mode
|
||||||
{
|
{
|
||||||
if (![request_modes containsObject: mode]) {
|
if ([request_modes containsObject: mode] == NO)
|
||||||
[request_modes addObject: mode];
|
{
|
||||||
[[NSRunLoop currentRunLoop] addPort: receive_port forMode: mode];
|
[request_modes addObject: mode];
|
||||||
|
[[NSRunLoop currentRunLoop] addPort: receive_port forMode: mode];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -431,12 +442,12 @@ static int messages_received_count;
|
||||||
|
|
||||||
- (id) init
|
- (id) init
|
||||||
{
|
{
|
||||||
id newPort = [[default_receive_port_class newForReceiving] autorelease];
|
NSPort *newPort;
|
||||||
id newConn = [NSConnection newForInPort: newPort
|
|
||||||
outPort: nil
|
newPort = [default_receive_port_class newForReceiving];
|
||||||
ancestorConnection: nil];
|
self = [self initWithReceivePort: newPort sendPort: nil];
|
||||||
[self release];
|
RELEASE(newPort);
|
||||||
return newConn;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -516,6 +527,33 @@ static int messages_received_count;
|
||||||
return is_valid;
|
return is_valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (BOOL) registerName: (NSString*)name
|
||||||
|
{
|
||||||
|
NSPortNameServer *svr = [NSPortNameServer defaultPortNameServer];
|
||||||
|
NSArray *names = [svr namesForPort: receive_port];
|
||||||
|
BOOL result = YES;
|
||||||
|
|
||||||
|
if (name != nil)
|
||||||
|
{
|
||||||
|
result = [svr registerPort: receive_port forName: name];
|
||||||
|
}
|
||||||
|
if (result == YES && [names count] > 0)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
for (i = 0; i < [names count]; i++)
|
||||||
|
{
|
||||||
|
NSString *tmp = [names objectAtIndex: i];
|
||||||
|
|
||||||
|
if ([tmp isEqualToString: name] == NO)
|
||||||
|
{
|
||||||
|
[svr removePort: receive_port forName: name];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
- (void) release
|
- (void) release
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -676,7 +714,7 @@ static int messages_received_count;
|
||||||
|
|
||||||
- (void) gcFinalize
|
- (void) gcFinalize
|
||||||
{
|
{
|
||||||
NSAutoreleasePool *arp = [NSAutoreleasePool new];
|
CREATE_AUTORELEASE_POOL(arp);
|
||||||
|
|
||||||
if (debug_connection)
|
if (debug_connection)
|
||||||
NSLog(@"finalising 0x%x\n", (gsaddr)self);
|
NSLog(@"finalising 0x%x\n", (gsaddr)self);
|
||||||
|
@ -690,26 +728,35 @@ static int messages_received_count;
|
||||||
|
|
||||||
/* Remove rootObject from root_object_dictionary
|
/* Remove rootObject from root_object_dictionary
|
||||||
if this is last connection */
|
if this is last connection */
|
||||||
if (![NSConnection connectionsCountWithInPort: receive_port])
|
if (receive_port != nil
|
||||||
[NSConnection setRootObject: nil forInPort: receive_port];
|
&& [NSConnection connectionsCountWithInPort: receive_port] == 0)
|
||||||
|
{
|
||||||
|
[NSConnection setRootObject: nil forInPort: receive_port];
|
||||||
|
}
|
||||||
|
|
||||||
/* Remove receive port from run loop. */
|
/* Remove receive port from run loop. */
|
||||||
[self setRequestMode: nil];
|
[self setRequestMode: nil];
|
||||||
[[NSRunLoop currentRunLoop] removePort: receive_port
|
if (receive_port != nil)
|
||||||
forMode: NSConnectionReplyMode];
|
{
|
||||||
[request_modes release];
|
[[NSRunLoop currentRunLoop] removePort: receive_port
|
||||||
|
forMode: NSConnectionReplyMode];
|
||||||
|
}
|
||||||
|
RELEASE(request_modes);
|
||||||
|
|
||||||
/* Finished with ports - releasing them may generate a notification */
|
/* Finished with ports - releasing them may generate a notification */
|
||||||
[receive_port release];
|
RELEASE(receive_port);
|
||||||
[send_port release];
|
RELEASE(send_port);
|
||||||
|
|
||||||
[proxiesHashGate lock];
|
[proxiesHashGate lock];
|
||||||
NSFreeMapTable (remote_proxies);
|
if (remote_proxies != 0)
|
||||||
NSFreeMapTable (local_objects);
|
NSFreeMapTable(remote_proxies);
|
||||||
NSFreeMapTable (local_targets);
|
if (local_objects != 0)
|
||||||
|
NSFreeMapTable(local_objects);
|
||||||
|
if (local_targets != 0)
|
||||||
|
NSFreeMapTable(local_targets);
|
||||||
[proxiesHashGate unlock];
|
[proxiesHashGate unlock];
|
||||||
|
|
||||||
[arp release];
|
RELEASE(arp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Getting and setting class variables */
|
/* Getting and setting class variables */
|
||||||
|
@ -817,7 +864,7 @@ static int messages_received_count;
|
||||||
newPort = [[default_receive_port_class newForReceiving] autorelease];
|
newPort = [[default_receive_port_class newForReceiving] autorelease];
|
||||||
newConn = [self newForInPort: newPort outPort: nil
|
newConn = [self newForInPort: newPort outPort: nil
|
||||||
ancestorConnection: nil];
|
ancestorConnection: nil];
|
||||||
[self setRootObject: anObj forInPort: newPort];
|
[[self class] setRootObject: anObj forInPort: newPort];
|
||||||
return newConn;
|
return newConn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -842,12 +889,15 @@ static int messages_received_count;
|
||||||
id newPort;
|
id newPort;
|
||||||
id newConn;
|
id newConn;
|
||||||
|
|
||||||
newPort = [default_receive_port_class newForReceivingFromRegisteredName: n
|
newPort = [default_receive_port_class newForReceiving];
|
||||||
fromPort: p];
|
newConn = [self alloc];
|
||||||
newConn = [self newForInPort: [newPort autorelease]
|
newConn = [newConn initWithReceivePort: newPort sendPort: nil];
|
||||||
outPort: nil
|
RELEASE(newPort);
|
||||||
ancestorConnection: nil];
|
[newConn setRootObject: anObj];
|
||||||
[self setRootObject: anObj forInPort: newPort];
|
if ([newConn registerName: n] == NO)
|
||||||
|
{
|
||||||
|
DESTROY(newConn);
|
||||||
|
}
|
||||||
return newConn;
|
return newConn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -889,163 +939,15 @@ static int messages_received_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This is the designated initializer for NSConnection */
|
|
||||||
|
|
||||||
+ (NSConnection*) newForInPort: (NSPort*)ip
|
+ (NSConnection*) newForInPort: (NSPort*)ip
|
||||||
outPort: (NSPort*)op
|
outPort: (NSPort*)op
|
||||||
ancestorConnection: (NSConnection*)ancestor
|
ancestorConnection: (NSConnection*)ancestor
|
||||||
{
|
{
|
||||||
NSNotificationCenter *nCenter;
|
NSConnection *conn;
|
||||||
NSConnection *newConn;
|
|
||||||
|
|
||||||
NSParameterAssert (ip);
|
conn = [self alloc];
|
||||||
|
conn = [conn initWithReceivePort: ip sendPort: op];
|
||||||
/* Find previously existing connection if there */
|
return conn;
|
||||||
newConn = [self connectionByInPort: ip outPort: op];
|
|
||||||
if (newConn)
|
|
||||||
{
|
|
||||||
if (debug_connection > 2)
|
|
||||||
NSLog(@"Found existing connection (0x%x) for \n\t%@\n\t%@\n",
|
|
||||||
(gsaddr)newConn, [ip description], [op description]);
|
|
||||||
return [newConn retain];
|
|
||||||
}
|
|
||||||
[connection_table_gate lock];
|
|
||||||
|
|
||||||
newConn = [[NSConnection alloc] _superInit];
|
|
||||||
if (debug_connection)
|
|
||||||
NSLog(@"Created new connection 0x%x\n\t%@\n\t%@\n",
|
|
||||||
(gsaddr)newConn, [ip description], [op description]);
|
|
||||||
newConn->is_valid = YES;
|
|
||||||
newConn->receive_port = ip;
|
|
||||||
[ip retain];
|
|
||||||
newConn->send_port = op;
|
|
||||||
[op retain];
|
|
||||||
newConn->message_count = 0;
|
|
||||||
newConn->rep_out_count = 0;
|
|
||||||
newConn->req_out_count = 0;
|
|
||||||
newConn->rep_in_count = 0;
|
|
||||||
newConn->req_in_count = 0;
|
|
||||||
|
|
||||||
/* This maps (void*)obj to (id)obj. The obj's are retained.
|
|
||||||
We use this instead of an NSHashTable because we only care about
|
|
||||||
the object's address, and don't want to send the -hash message to it. */
|
|
||||||
newConn->local_objects =
|
|
||||||
NSCreateMapTable (NSNonOwnedPointerMapKeyCallBacks,
|
|
||||||
NSObjectMapValueCallBacks, 0);
|
|
||||||
|
|
||||||
/* This maps handles for local objects to their local proxies. */
|
|
||||||
newConn->local_targets =
|
|
||||||
NSCreateMapTable (NSIntMapKeyCallBacks,
|
|
||||||
NSNonOwnedPointerMapValueCallBacks, 0);
|
|
||||||
|
|
||||||
/* This maps [proxy targetForProxy] to proxy. The proxy's are retained. */
|
|
||||||
newConn->remote_proxies =
|
|
||||||
NSCreateMapTable (NSIntMapKeyCallBacks,
|
|
||||||
NSNonOwnedPointerMapValueCallBacks, 0);
|
|
||||||
|
|
||||||
newConn->reply_timeout = [self defaultInTimeout];
|
|
||||||
newConn->request_timeout = [self defaultOutTimeout];
|
|
||||||
newConn->encoding_class = default_encoding_class;
|
|
||||||
|
|
||||||
/* xxx ANCESTOR argument is currently ignored; in the future it
|
|
||||||
will be removed. */
|
|
||||||
/* xxx It this the correct behavior? */
|
|
||||||
if (!(ancestor = NSMapGet (receive_port_2_ancestor, ip)))
|
|
||||||
{
|
|
||||||
NSMapInsert (receive_port_2_ancestor, ip, newConn);
|
|
||||||
/* 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
|
|
||||||
on this in port. */
|
|
||||||
/* xxx Could it happen that this connection was invalidated, but
|
|
||||||
the others would still be OK? That would cause problems.
|
|
||||||
No. I don't think that can happen. */
|
|
||||||
[(InPort*)ip setReceivedPacketInvocation: (id)[self class]];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ancestor)
|
|
||||||
{
|
|
||||||
newConn->receive_port_class = [ancestor receivePortClass];
|
|
||||||
newConn->send_port_class = [ancestor sendPortClass];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
newConn->receive_port_class = default_receive_port_class;
|
|
||||||
newConn->send_port_class = default_send_port_class;
|
|
||||||
}
|
|
||||||
newConn->independent_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). */
|
|
||||||
|
|
||||||
/* Preferred OpenStep version, which just allows the returning of BOOL */
|
|
||||||
if ([[ancestor delegate] respondsTo: @selector(connection: shouldMakeNewConnection: )])
|
|
||||||
{
|
|
||||||
if (![[ancestor delegate] connection: ancestor
|
|
||||||
shouldMakeNewConnection: (NSConnection*)newConn])
|
|
||||||
{
|
|
||||||
[connection_table_gate unlock];
|
|
||||||
[newConn release];
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Deprecated OpenStep version, which just allows the returning of BOOL */
|
|
||||||
if ([[ancestor delegate] respondsTo: @selector(makeNewConnection: sender: )])
|
|
||||||
{
|
|
||||||
if (![[ancestor delegate] makeNewConnection: (NSConnection*)newConn
|
|
||||||
sender: ancestor])
|
|
||||||
{
|
|
||||||
[connection_table_gate unlock];
|
|
||||||
[newConn release];
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Here is the GNUstep version, which allows the delegate to specify
|
|
||||||
a substitute. Note: The delegate is responsible for freeing
|
|
||||||
newConn if it returns something different. */
|
|
||||||
if ([[ancestor delegate] respondsTo: @selector(connection: didConnect: )])
|
|
||||||
newConn = [[ancestor delegate] connection: ancestor
|
|
||||||
didConnect: newConn];
|
|
||||||
|
|
||||||
/* Register ourselves for invalidation notification when the
|
|
||||||
ports become invalid. */
|
|
||||||
nCenter = [NSNotificationCenter defaultCenter];
|
|
||||||
[nCenter addObserver: newConn
|
|
||||||
selector: @selector(portIsInvalid: )
|
|
||||||
name: NSPortDidBecomeInvalidNotification
|
|
||||||
object: ip];
|
|
||||||
if (op)
|
|
||||||
[nCenter addObserver: newConn
|
|
||||||
selector: @selector(portIsInvalid: )
|
|
||||||
name: NSPortDidBecomeInvalidNotification
|
|
||||||
object: op];
|
|
||||||
/* if OP is nil, making this notification request would have
|
|
||||||
registered us to receive all NSPortDidBecomeInvalidNotification
|
|
||||||
requests, independent of which port posted them. This isn't
|
|
||||||
what we want. */
|
|
||||||
|
|
||||||
/* In order that connections may be deallocated - there is an
|
|
||||||
implementation of [-release] to automatically remove the connection
|
|
||||||
from this array when it is the only thing retaining it. */
|
|
||||||
NSHashInsert(connection_table, (void*)newConn);
|
|
||||||
[connection_table_gate unlock];
|
|
||||||
|
|
||||||
[[NSNotificationCenter defaultCenter]
|
|
||||||
postNotificationName: NSConnectionDidInitializeNotification
|
|
||||||
object: newConn];
|
|
||||||
|
|
||||||
return newConn;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (NSConnection*) connectionByInPort: (NSPort*)ip
|
+ (NSConnection*) connectionByInPort: (NSPort*)ip
|
||||||
|
@ -2068,24 +1970,24 @@ static int messages_received_count;
|
||||||
[self _release_targets: &target count: 1];
|
[self _release_targets: &target count: 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSArray *) localObjects
|
- (NSArray*) localObjects
|
||||||
{
|
{
|
||||||
id c;
|
NSArray *c;
|
||||||
|
|
||||||
/* Don't assert (is_valid); */
|
/* Don't assert (is_valid); */
|
||||||
[proxiesHashGate lock];
|
[proxiesHashGate lock];
|
||||||
c = NSAllMapTableValues (local_objects);
|
c = NSAllMapTableValues(local_objects);
|
||||||
[proxiesHashGate unlock];
|
[proxiesHashGate unlock];
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSArray *) proxies
|
- (NSArray*) proxies
|
||||||
{
|
{
|
||||||
id c;
|
NSArray *c;
|
||||||
|
|
||||||
/* Don't assert (is_valid); */
|
/* Don't assert (is_valid); */
|
||||||
[proxiesHashGate lock];
|
[proxiesHashGate lock];
|
||||||
c = NSAllMapTableValues (remote_proxies);
|
c = NSAllMapTableValues(remote_proxies);
|
||||||
[proxiesHashGate unlock];
|
[proxiesHashGate unlock];
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
@ -2270,21 +2172,23 @@ static int messages_received_count;
|
||||||
*/
|
*/
|
||||||
- (void) portIsInvalid: notification
|
- (void) portIsInvalid: notification
|
||||||
{
|
{
|
||||||
if (is_valid) {
|
if (is_valid)
|
||||||
id port = [notification object];
|
{
|
||||||
|
id port = [notification object];
|
||||||
|
|
||||||
if (debug_connection)
|
if (debug_connection)
|
||||||
NSLog(@"Received port invalidation notification for "
|
{
|
||||||
@"connection 0x%x\n\t%@\n", (gsaddr)self,
|
NSLog(@"Received port invalidation notification for "
|
||||||
[port description]);
|
@"connection 0x%x\n\t%@\n", (gsaddr)self, port);
|
||||||
|
}
|
||||||
|
|
||||||
/* We shouldn't be getting any port invalidation notifications,
|
/* We shouldn't be getting any port invalidation notifications,
|
||||||
except from our own ports; this is how we registered ourselves
|
except from our own ports; this is how we registered ourselves
|
||||||
with the NSNotificationCenter in
|
with the NSNotificationCenter in
|
||||||
+newForInPort: outPort: ancestorConnection. */
|
+newForInPort: outPort: ancestorConnection. */
|
||||||
NSParameterAssert (port == receive_port || port == send_port);
|
NSParameterAssert (port == receive_port || port == send_port);
|
||||||
|
|
||||||
[self invalidate];
|
[self invalidate];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2297,32 +2201,188 @@ static int messages_received_count;
|
||||||
+ (NSConnection*) connectionWithReceivePort: (NSPort*)r
|
+ (NSConnection*) connectionWithReceivePort: (NSPort*)r
|
||||||
sendPort: (NSPort*)s
|
sendPort: (NSPort*)s
|
||||||
{
|
{
|
||||||
NSConnection *c;
|
NSConnection *c;
|
||||||
|
|
||||||
c = [self newForInPort: r outPort: s ancestorConnection: nil];
|
c = [self alloc];
|
||||||
return [c autorelease];
|
c = [self initWithReceivePort: r sendPort: s];
|
||||||
|
return AUTORELEASE(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
- initWithReceivePort: (NSPort*)r
|
/* This is the designated initializer for NSConnection */
|
||||||
sendPort: (NSPort*)s
|
- (id) initWithReceivePort: (NSPort*)r
|
||||||
|
sendPort: (NSPort*)s
|
||||||
{
|
{
|
||||||
[self dealloc];
|
NSNotificationCenter *nCenter;
|
||||||
return [NSConnection newForInPort: r outPort: s ancestorConnection: nil];
|
NSConnection *conn;
|
||||||
|
id del;
|
||||||
|
|
||||||
|
NSParameterAssert(r);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find previously existing connection if there
|
||||||
|
*/
|
||||||
|
conn = [NSConnection connectionByInPort: r outPort: s];
|
||||||
|
if (conn != nil)
|
||||||
|
{
|
||||||
|
if (debug_connection > 2)
|
||||||
|
{
|
||||||
|
NSLog(@"Found existing connection (0x%x) for \n\t%@\n\t%@\n",
|
||||||
|
(gsaddr)conn, r, s);
|
||||||
|
}
|
||||||
|
RELEASE(self);
|
||||||
|
return RETAIN(conn);
|
||||||
|
}
|
||||||
|
[connection_table_gate lock];
|
||||||
|
|
||||||
|
if (debug_connection)
|
||||||
|
{
|
||||||
|
NSLog(@"Initialised new connection 0x%x\n\t%@\n\t%@\n",
|
||||||
|
(gsaddr)self, r, s);
|
||||||
|
}
|
||||||
|
is_valid = YES;
|
||||||
|
receive_port = RETAIN(r);
|
||||||
|
send_port = RETAIN(s);
|
||||||
|
message_count = 0;
|
||||||
|
rep_out_count = 0;
|
||||||
|
req_out_count = 0;
|
||||||
|
rep_in_count = 0;
|
||||||
|
req_in_count = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This maps (void*)obj to (id)obj. The obj's are retained.
|
||||||
|
* We use this instead of an NSHashTable because we only care about
|
||||||
|
* the object's address, and don't want to send the -hash message to it.
|
||||||
|
*/
|
||||||
|
local_objects =
|
||||||
|
NSCreateMapTable(NSNonOwnedPointerMapKeyCallBacks,
|
||||||
|
NSObjectMapValueCallBacks, 0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This maps handles for local objects to their local proxies.
|
||||||
|
*/
|
||||||
|
local_targets =
|
||||||
|
NSCreateMapTable(NSIntMapKeyCallBacks,
|
||||||
|
NSNonOwnedPointerMapValueCallBacks, 0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This maps [proxy targetForProxy] to proxy. The proxy's are retained.
|
||||||
|
*/
|
||||||
|
remote_proxies =
|
||||||
|
NSCreateMapTable(NSIntMapKeyCallBacks,
|
||||||
|
NSNonOwnedPointerMapValueCallBacks, 0);
|
||||||
|
|
||||||
|
reply_timeout = default_reply_timeout;
|
||||||
|
request_timeout = default_request_timeout;
|
||||||
|
encoding_class = default_encoding_class;
|
||||||
|
|
||||||
|
/* xxx It this the correct behavior? */
|
||||||
|
if ((conn = NSMapGet(receive_port_2_ancestor, r)) == nil)
|
||||||
|
{
|
||||||
|
NSMapInsert(receive_port_2_ancestor, r, self);
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
* on this in port.
|
||||||
|
*/
|
||||||
|
/* xxx Could it happen that this connection was invalidated, but
|
||||||
|
the others would still be OK? That would cause problems.
|
||||||
|
No. I don't think that can happen. */
|
||||||
|
[(InPort*)r setReceivedPacketInvocation: (id)[self class]];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conn != nil)
|
||||||
|
{
|
||||||
|
receive_port_class = [conn receivePortClass];
|
||||||
|
send_port_class = [conn sendPortClass];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
receive_port_class = default_receive_port_class;
|
||||||
|
send_port_class = default_send_port_class;
|
||||||
|
}
|
||||||
|
independent_queueing = NO;
|
||||||
|
reply_depth = 0;
|
||||||
|
delegate = nil;
|
||||||
|
/*
|
||||||
|
* Set up request modes array and make sure the receiving port is
|
||||||
|
* added to the run loop to get data.
|
||||||
|
*/
|
||||||
|
request_modes
|
||||||
|
= RETAIN([NSMutableArray arrayWithObject: NSDefaultRunLoopMode]);
|
||||||
|
[[NSRunLoop currentRunLoop] addPort: (NSPort*)r
|
||||||
|
forMode: NSDefaultRunLoopMode];
|
||||||
|
[[NSRunLoop currentRunLoop] addPort: (NSPort*)r
|
||||||
|
forMode: NSConnectionReplyMode];
|
||||||
|
|
||||||
|
/* Ask the delegate for permission, (OpenStep-style and GNUstep-style). */
|
||||||
|
|
||||||
|
/* Preferred OpenStep version, which just allows the returning of BOOL */
|
||||||
|
del = [conn delegate];
|
||||||
|
if ([del respondsTo: @selector(connection:shouldMakeNewConnection:)])
|
||||||
|
{
|
||||||
|
if ([del connection: conn shouldMakeNewConnection: self] == NO)
|
||||||
|
{
|
||||||
|
[connection_table_gate unlock];
|
||||||
|
RELEASE(self);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Deprecated OpenStep version, which just allows the returning of BOOL */
|
||||||
|
if ([del respondsTo: @selector(makeNewConnection:sender:)])
|
||||||
|
{
|
||||||
|
if (![del makeNewConnection: self sender: conn])
|
||||||
|
{
|
||||||
|
[connection_table_gate unlock];
|
||||||
|
RELEASE(self);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Here is the GNUstep version, which allows the delegate to specify
|
||||||
|
a substitute. Note: The delegate is responsible for freeing
|
||||||
|
newConn if it returns something different. */
|
||||||
|
if ([del respondsTo: @selector(connection:didConnect:)])
|
||||||
|
self = [del connection: conn didConnect: self];
|
||||||
|
|
||||||
|
/* Register ourselves for invalidation notification when the
|
||||||
|
ports become invalid. */
|
||||||
|
nCenter = [NSNotificationCenter defaultCenter];
|
||||||
|
[nCenter addObserver: self
|
||||||
|
selector: @selector(portIsInvalid:)
|
||||||
|
name: NSPortDidBecomeInvalidNotification
|
||||||
|
object: r];
|
||||||
|
if (s != nil)
|
||||||
|
[nCenter addObserver: self
|
||||||
|
selector: @selector(portIsInvalid:)
|
||||||
|
name: NSPortDidBecomeInvalidNotification
|
||||||
|
object: s];
|
||||||
|
|
||||||
|
/* In order that connections may be deallocated - there is an
|
||||||
|
implementation of [-release] to automatically remove the connection
|
||||||
|
from this array when it is the only thing retaining it. */
|
||||||
|
NSHashInsert(connection_table, (void*)self);
|
||||||
|
[connection_table_gate unlock];
|
||||||
|
|
||||||
|
[[NSNotificationCenter defaultCenter]
|
||||||
|
postNotificationName: NSConnectionDidInitializeNotification
|
||||||
|
object: self];
|
||||||
|
|
||||||
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSPort*) receivePort
|
- (NSPort*) receivePort
|
||||||
{
|
{
|
||||||
return receive_port;
|
return receive_port;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) runInNewThread
|
- (void) runInNewThread
|
||||||
{
|
{
|
||||||
[self notImplemented: _cmd];
|
[self notImplemented: _cmd];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSPort*) sendPort
|
- (NSPort*) sendPort
|
||||||
{
|
{
|
||||||
return send_port;
|
return send_port;
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -558,7 +558,7 @@ typedef enum {
|
||||||
unsigned portNum = 0;
|
unsigned portNum = 0;
|
||||||
unsigned len;
|
unsigned len;
|
||||||
NSMutableArray *array;
|
NSMutableArray *array;
|
||||||
NSDate *limit = [NSDate dateWithTimeIntervalSinceNow: timeout];
|
NSDate *limit;
|
||||||
|
|
||||||
if (name == nil)
|
if (name == nil)
|
||||||
{
|
{
|
||||||
|
@ -579,6 +579,8 @@ typedef enum {
|
||||||
GDO_NAME_MAX_LEN];
|
GDO_NAME_MAX_LEN];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
limit = [NSDate dateWithTimeIntervalSinceNow: timeout];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get one or more host addresses in network byte order.
|
* get one or more host addresses in network byte order.
|
||||||
*/
|
*/
|
||||||
|
@ -626,7 +628,7 @@ typedef enum {
|
||||||
if (numSvrs == 0)
|
if (numSvrs == 0)
|
||||||
{
|
{
|
||||||
[NSException raise: NSInternalInconsistencyException
|
[NSException raise: NSInternalInconsistencyException
|
||||||
format: @"failed to get list of name servers on net"];
|
format: @"failed to get list of name servers"];
|
||||||
}
|
}
|
||||||
tmp = com;
|
tmp = com;
|
||||||
com = nil;
|
com = nil;
|
||||||
|
@ -715,7 +717,8 @@ typedef enum {
|
||||||
[com close];
|
[com close];
|
||||||
if ([com state] == GSPC_DONE)
|
if ([com state] == GSPC_DONE)
|
||||||
{
|
{
|
||||||
portNum = GSSwapBigI32ToHost(*(gsu32*)[[com data] bytes]);
|
portNum
|
||||||
|
= GSSwapBigI32ToHost(*(gsu32*)[[com data] bytes]);
|
||||||
if (portNum != 0)
|
if (portNum != 0)
|
||||||
{
|
{
|
||||||
singleServer = [com addr];
|
singleServer = [com addr];
|
||||||
|
@ -787,7 +790,7 @@ typedef enum {
|
||||||
NSRunLoop *loop = [NSRunLoop currentRunLoop];
|
NSRunLoop *loop = [NSRunLoop currentRunLoop];
|
||||||
GSPortCom *com;
|
GSPortCom *com;
|
||||||
unsigned len;
|
unsigned len;
|
||||||
NSDate *limit = [NSDate dateWithTimeIntervalSinceNow: timeout];
|
NSDate *limit;
|
||||||
|
|
||||||
if (name == nil)
|
if (name == nil)
|
||||||
{
|
{
|
||||||
|
@ -811,6 +814,8 @@ typedef enum {
|
||||||
format: @"name of port is too long (max %d) bytes",
|
format: @"name of port is too long (max %d) bytes",
|
||||||
GDO_NAME_MAX_LEN];
|
GDO_NAME_MAX_LEN];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
limit = [NSDate dateWithTimeIntervalSinceNow: timeout];
|
||||||
/*
|
/*
|
||||||
* Lock out other threads while doing I/O to gdomap
|
* Lock out other threads while doing I/O to gdomap
|
||||||
*/
|
*/
|
||||||
|
@ -1013,6 +1018,27 @@ typedef enum {
|
||||||
|
|
||||||
@implementation NSPortNameServer (GNUstep)
|
@implementation NSPortNameServer (GNUstep)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the names under which the port is currently registered.
|
||||||
|
*/
|
||||||
|
- (NSArray*) namesForPort: (NSPort*)port
|
||||||
|
{
|
||||||
|
NSArray *names;
|
||||||
|
|
||||||
|
if (port == nil)
|
||||||
|
{
|
||||||
|
[NSException raise: NSInvalidArgumentException
|
||||||
|
format: @"attempt to get names for nil port"];
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Lock out other threads while grabbing port names.
|
||||||
|
*/
|
||||||
|
[serverLock lock];
|
||||||
|
names = [(NSSet*)NSMapGet(_portMap, port) allObjects];
|
||||||
|
[serverLock unlock];
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Remove all names for a particular port - used when a port is
|
* Remove all names for a particular port - used when a port is
|
||||||
* invalidated.
|
* invalidated.
|
||||||
|
@ -1023,7 +1049,7 @@ typedef enum {
|
||||||
NS_DURING
|
NS_DURING
|
||||||
{
|
{
|
||||||
NSMutableSet *known = (NSMutableSet*)NSMapGet(_portMap, port);
|
NSMutableSet *known = (NSMutableSet*)NSMapGet(_portMap, port);
|
||||||
NSString *name;
|
NSString *name;
|
||||||
|
|
||||||
while ((name = [known anyObject]) != nil)
|
while ((name = [known anyObject]) != nil)
|
||||||
{
|
{
|
||||||
|
@ -1036,7 +1062,31 @@ typedef enum {
|
||||||
[localException raise];
|
[localException raise];
|
||||||
}
|
}
|
||||||
NS_ENDHANDLER
|
NS_ENDHANDLER
|
||||||
|
[serverLock unlock];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remove name for port iff it is registered.
|
||||||
|
*/
|
||||||
|
- (void) removePort: (NSPort*)port forName: (NSString*)name
|
||||||
|
{
|
||||||
[serverLock lock];
|
[serverLock lock];
|
||||||
|
NS_DURING
|
||||||
|
{
|
||||||
|
NSMutableSet *known = (NSMutableSet*)NSMapGet(_portMap, port);
|
||||||
|
|
||||||
|
if ([known member: name] != nil)
|
||||||
|
{
|
||||||
|
[self removePortForName: name];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NS_HANDLER
|
||||||
|
{
|
||||||
|
[serverLock unlock];
|
||||||
|
[localException raise];
|
||||||
|
}
|
||||||
|
NS_ENDHANDLER
|
||||||
|
[serverLock unlock];
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
|
@ -222,7 +222,7 @@ static Class NSMutableSet_concrete_class;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Same as NSArray */
|
/* Same as NSArray */
|
||||||
- initWithObjects: firstObject, ...
|
- (id) initWithObjects: firstObject, ...
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, firstObject);
|
va_start(ap, firstObject);
|
||||||
|
@ -232,12 +232,12 @@ static Class NSMutableSet_concrete_class;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Override superclass's designated initializer */
|
/* Override superclass's designated initializer */
|
||||||
- init
|
- (id) init
|
||||||
{
|
{
|
||||||
return [self initWithObjects: NULL count: 0];
|
return [self initWithObjects: NULL count: 0];
|
||||||
}
|
}
|
||||||
|
|
||||||
- initWithArray: (NSArray*)other
|
- (id) initWithArray: (NSArray*)other
|
||||||
{
|
{
|
||||||
unsigned count = [other count];
|
unsigned count = [other count];
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue