mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-31 16:50:58 +00:00
Updated distributed objects code to cope with triangular relationships -
Process A vends object to B which vends object to C. There was a problem where B could give the object to C and release it in A before C could get a proxy to the original in A. Now we give it 30 seconds to establish the connection. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@2824 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
f3a3fe0f57
commit
fe8b8fa3d4
10 changed files with 2023 additions and 871 deletions
|
@ -61,7 +61,7 @@ enum {
|
||||||
METHODTYPE_REQUEST, /* these two only needed with NeXT runtime */
|
METHODTYPE_REQUEST, /* these two only needed with NeXT runtime */
|
||||||
METHODTYPE_REPLY, /* these two only needed with NeXT runtime */
|
METHODTYPE_REPLY, /* these two only needed with NeXT runtime */
|
||||||
PROXY_RELEASE,
|
PROXY_RELEASE,
|
||||||
PROXY_RETAIN
|
PROXY_RETAIN,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -210,11 +210,11 @@ extern NSString *NSConnectionProxyCount; /* Objects received */
|
||||||
|
|
||||||
/* Only subclassers and power-users need worry about these */
|
/* Only subclassers and power-users need worry about these */
|
||||||
- (void) addProxy: (NSDistantObject*)aProxy;
|
- (void) addProxy: (NSDistantObject*)aProxy;
|
||||||
- (BOOL) includesProxyForTarget: (unsigned)target;
|
- (id) includesProxyForTarget: (void*)target;
|
||||||
- (void) removeProxy: (NSDistantObject*)aProxy;
|
- (void) removeProxy: (NSDistantObject*)aProxy;
|
||||||
- (id <Collecting>) localObjects;
|
- (id <Collecting>) localObjects;
|
||||||
- (void) addLocalObject: anObj;
|
- (void) addLocalObject: anObj;
|
||||||
- (BOOL) includesLocalObject: anObj;
|
- (id) includesLocalObject: anObj;
|
||||||
- (void) removeLocalObject: anObj;
|
- (void) removeLocalObject: anObj;
|
||||||
- (retval_t) forwardForProxy: (NSDistantObject*)object
|
- (retval_t) forwardForProxy: (NSDistantObject*)object
|
||||||
selector: (SEL)sel
|
selector: (SEL)sel
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
NSConnection* _connection;
|
NSConnection* _connection;
|
||||||
id _object;
|
id _object;
|
||||||
BOOL _isLocal;
|
BOOL _isLocal;
|
||||||
|
BOOL _isVended;
|
||||||
id _protocol;
|
id _protocol;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,6 +61,22 @@ NSString *NSConnectionRequestsSent = @"NSConnectionRequestsSent";
|
||||||
NSString *NSConnectionLocalCount = @"NSConnectionLocalCount";
|
NSString *NSConnectionLocalCount = @"NSConnectionLocalCount";
|
||||||
NSString *NSConnectionProxyCount = @"NSConnectionProxyCount";
|
NSString *NSConnectionProxyCount = @"NSConnectionProxyCount";
|
||||||
|
|
||||||
|
@interface NSDistantObject (NSConnection)
|
||||||
|
- (BOOL) isVended;
|
||||||
|
- (void) setVended;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation NSDistantObject (NSConnection)
|
||||||
|
- (BOOL) isVended
|
||||||
|
{
|
||||||
|
return _isVended;
|
||||||
|
}
|
||||||
|
- (void) setVended
|
||||||
|
{
|
||||||
|
_isVended = YES;
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ConnectionLocalCounter is a trivial class to keep track of how
|
* ConnectionLocalCounter is a trivial class to keep track of how
|
||||||
* many different connections a particular local object is vended
|
* many different connections a particular local object is vended
|
||||||
|
@ -104,6 +120,57 @@ NSString *NSConnectionProxyCount = @"NSConnectionProxyCount";
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CachedLocalObject is a trivial class to keep track of how
|
||||||
|
* many different connections a particular local object is vended
|
||||||
|
* over. This is required so that we know when to remove an object
|
||||||
|
* from the global list when it is removed from the list of objects
|
||||||
|
* vended on a particular connection.
|
||||||
|
*/
|
||||||
|
@interface CachedLocalObject : NSObject
|
||||||
|
{
|
||||||
|
id obj;
|
||||||
|
int time;
|
||||||
|
}
|
||||||
|
- (BOOL)countdown;
|
||||||
|
- (id) obj;
|
||||||
|
+ (CachedLocalObject*) itemWithObject: (id)o time: (int)t;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation CachedLocalObject
|
||||||
|
|
||||||
|
- (void) dealloc
|
||||||
|
{
|
||||||
|
[obj release];
|
||||||
|
[super dealloc];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL) countdown
|
||||||
|
{
|
||||||
|
if (time-- > 0)
|
||||||
|
return YES;
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id) obj
|
||||||
|
{
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (CachedLocalObject*) itemWithObject: (id)o time: (int)t
|
||||||
|
{
|
||||||
|
CachedLocalObject *item = [self alloc];
|
||||||
|
|
||||||
|
item = [super init];
|
||||||
|
item->obj = [o retain];
|
||||||
|
item->time = t;
|
||||||
|
return [item autorelease];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
@interface NSConnection (GettingCoderInterface)
|
@interface NSConnection (GettingCoderInterface)
|
||||||
- (void) _handleRmc: rmc;
|
- (void) _handleRmc: rmc;
|
||||||
|
@ -116,6 +183,7 @@ NSString *NSConnectionProxyCount = @"NSConnectionProxyCount";
|
||||||
|
|
||||||
@interface NSConnection (Private)
|
@interface NSConnection (Private)
|
||||||
- _superInit;
|
- _superInit;
|
||||||
|
+ setDebug: (int)val;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
#define proxiesHashGate refGate
|
#define proxiesHashGate refGate
|
||||||
|
@ -167,6 +235,7 @@ static id default_encoding_class;
|
||||||
static id default_decoding_class;
|
static id default_decoding_class;
|
||||||
static int default_reply_timeout;
|
static int default_reply_timeout;
|
||||||
static int default_request_timeout;
|
static int default_request_timeout;
|
||||||
|
static NSTimer *timer;
|
||||||
|
|
||||||
static int debug_connection = 0;
|
static int debug_connection = 0;
|
||||||
|
|
||||||
|
@ -186,6 +255,7 @@ static Lock *root_object_dictionary_gate;
|
||||||
static NSMapTable *receive_port_2_ancestor;
|
static NSMapTable *receive_port_2_ancestor;
|
||||||
|
|
||||||
static NSMapTable *all_connections_local_targets = NULL;
|
static NSMapTable *all_connections_local_targets = NULL;
|
||||||
|
static NSMapTable *all_connections_local_cached = NULL;
|
||||||
|
|
||||||
/* rmc handling */
|
/* rmc handling */
|
||||||
static NSMutableArray *received_request_rmc_queue;
|
static NSMutableArray *received_request_rmc_queue;
|
||||||
|
@ -256,6 +326,9 @@ static int messages_received_count;
|
||||||
all_connections_local_targets =
|
all_connections_local_targets =
|
||||||
NSCreateMapTable (NSNonOwnedPointerMapKeyCallBacks,
|
NSCreateMapTable (NSNonOwnedPointerMapKeyCallBacks,
|
||||||
NSObjectMapValueCallBacks, 0);
|
NSObjectMapValueCallBacks, 0);
|
||||||
|
all_connections_local_cached =
|
||||||
|
NSCreateMapTable (NSNonOwnedPointerMapKeyCallBacks,
|
||||||
|
NSObjectMapValueCallBacks, 0);
|
||||||
received_request_rmc_queue = [[NSMutableArray alloc] initWithCapacity:32];
|
received_request_rmc_queue = [[NSMutableArray alloc] initWithCapacity:32];
|
||||||
received_request_rmc_queue_gate = [Lock new];
|
received_request_rmc_queue_gate = [Lock new];
|
||||||
received_reply_rmc_queue = [[NSMutableArray alloc] initWithCapacity:32];
|
received_reply_rmc_queue = [[NSMutableArray alloc] initWithCapacity:32];
|
||||||
|
@ -294,6 +367,21 @@ static int messages_received_count;
|
||||||
return [self rootProxyAtPort: [p autorelease]];
|
return [self rootProxyAtPort: [p autorelease]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+ (void) timeout: (NSTimer*)t
|
||||||
|
{
|
||||||
|
NSArray *cached_locals;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
cached_locals = NSAllMapTableValues(all_connections_local_cached);
|
||||||
|
for (i = [cached_locals count]; i > 0; i--) {
|
||||||
|
CachedLocalObject *item = [cached_locals objectAtIndex: i-1];
|
||||||
|
|
||||||
|
if ([item countdown] == NO) {
|
||||||
|
NSMapRemove(all_connections_local_cached, [item obj]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (void) addRequestMode: (NSString*)mode
|
- (void) addRequestMode: (NSString*)mode
|
||||||
{
|
{
|
||||||
if (![request_modes containsObject:mode]) {
|
if (![request_modes containsObject:mode]) {
|
||||||
|
@ -306,7 +394,7 @@ static int messages_received_count;
|
||||||
- (void) dealloc
|
- (void) dealloc
|
||||||
{
|
{
|
||||||
if (debug_connection)
|
if (debug_connection)
|
||||||
printf("deallocating 0x%x\n", (unsigned)self);
|
NSLog(@"deallocating 0x%x\n", (unsigned)self);
|
||||||
[self invalidate];
|
[self invalidate];
|
||||||
|
|
||||||
/* Remove rootObject from root_object_dictionary
|
/* Remove rootObject from root_object_dictionary
|
||||||
|
@ -424,10 +512,8 @@ static int messages_received_count;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (debug_connection)
|
if (debug_connection)
|
||||||
fprintf(stderr, "Invalidating connection 0x%x\n\t%s\n\t%s\n",
|
NSLog(@"Invalidating connection 0x%x\n\t%@\n\t%@\n", (unsigned)self,
|
||||||
(unsigned)self,
|
[receive_port description], [send_port description]);
|
||||||
[[receive_port description] cStringNoCopy],
|
|
||||||
[[send_port description] cStringNoCopy]);
|
|
||||||
|
|
||||||
[NotificationDispatcher
|
[NotificationDispatcher
|
||||||
postNotificationName: NSConnectionDidDieNotification
|
postNotificationName: NSConnectionDidDieNotification
|
||||||
|
@ -456,6 +542,9 @@ static int messages_received_count;
|
||||||
[super retain];
|
[super retain];
|
||||||
[connection_array_gate lock];
|
[connection_array_gate lock];
|
||||||
[connection_array removeObject: self];
|
[connection_array removeObject: self];
|
||||||
|
[timer invalidate];
|
||||||
|
timer = nil;
|
||||||
|
NSResetMapTable(all_connections_local_cached);
|
||||||
[connection_array_gate unlock];
|
[connection_array_gate unlock];
|
||||||
[super release];
|
[super release];
|
||||||
}
|
}
|
||||||
|
@ -773,10 +862,8 @@ static int messages_received_count;
|
||||||
|
|
||||||
newConn = [[NSConnection alloc] _superInit];
|
newConn = [[NSConnection alloc] _superInit];
|
||||||
if (debug_connection)
|
if (debug_connection)
|
||||||
fprintf(stderr, "Created new connection 0x%x\n\t%s\n\t%s\n",
|
NSLog(@"Created new connection 0x%x\n\t%@\n\t%@\n",
|
||||||
(unsigned)newConn,
|
(unsigned)newConn, [ip description], [op description]);
|
||||||
[[ip description] cStringNoCopy],
|
|
||||||
[[op description] cStringNoCopy]);
|
|
||||||
newConn->is_valid = 1;
|
newConn->is_valid = 1;
|
||||||
newConn->receive_port = ip;
|
newConn->receive_port = ip;
|
||||||
[ip retain];
|
[ip retain];
|
||||||
|
@ -973,6 +1060,10 @@ static int messages_received_count;
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+ setDebug: (int)val
|
||||||
|
{
|
||||||
|
debug_connection = val;
|
||||||
|
}
|
||||||
|
|
||||||
/* Creating new rmc's for encoding requests and replies */
|
/* Creating new rmc's for encoding requests and replies */
|
||||||
|
|
||||||
|
@ -1070,6 +1161,8 @@ static int messages_received_count;
|
||||||
out_parameters = mframe_dissect_call (argframe, type, encoder);
|
out_parameters = mframe_dissect_call (argframe, type, encoder);
|
||||||
/* Send the rmc */
|
/* Send the rmc */
|
||||||
[op dismiss];
|
[op dismiss];
|
||||||
|
if (debug_connection > 1)
|
||||||
|
NSLog(@"Sent message to 0x%x\n", (unsigned)self);
|
||||||
req_out_count++; /* Sent a request. */
|
req_out_count++; /* Sent a request. */
|
||||||
|
|
||||||
/* Get the reply rmc, and decode it. */
|
/* Get the reply rmc, and decode it. */
|
||||||
|
@ -1223,6 +1316,8 @@ static int messages_received_count;
|
||||||
at:&forward_type
|
at:&forward_type
|
||||||
withName:NULL];
|
withName:NULL];
|
||||||
|
|
||||||
|
if (debug_connection > 1)
|
||||||
|
NSLog(@"Handling message from 0x%x\n", (unsigned)self);
|
||||||
req_in_count++; /* Handling an incoming request. */
|
req_in_count++; /* Handling an incoming request. */
|
||||||
mframe_do_call (forward_type, decoder, encoder);
|
mframe_do_call (forward_type, decoder, encoder);
|
||||||
[op dismiss];
|
[op dismiss];
|
||||||
|
@ -1268,12 +1363,12 @@ static int messages_received_count;
|
||||||
NSParameterAssert([rmc connection] == self);
|
NSParameterAssert([rmc connection] == self);
|
||||||
[op encodeObject: rootObject withName: @"root object"];
|
[op encodeObject: rootObject withName: @"root object"];
|
||||||
[op dismiss];
|
[op dismiss];
|
||||||
|
[rmc dismiss];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) _service_release: rmc forConnection: receiving_connection
|
- (void) _service_release: rmc forConnection: receiving_connection
|
||||||
{
|
{
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
unsigned int target;
|
|
||||||
unsigned int pos;
|
unsigned int pos;
|
||||||
|
|
||||||
NSParameterAssert (is_valid);
|
NSParameterAssert (is_valid);
|
||||||
|
@ -1288,11 +1383,23 @@ static int messages_received_count;
|
||||||
withName: NULL];
|
withName: NULL];
|
||||||
|
|
||||||
for (pos = 0; pos < count; pos++) {
|
for (pos = 0; pos < count; pos++) {
|
||||||
|
unsigned int target;
|
||||||
|
char vended;
|
||||||
|
NSDistantObject *prox;
|
||||||
|
|
||||||
[rmc decodeValueOfCType: @encode(typeof(target))
|
[rmc decodeValueOfCType: @encode(typeof(target))
|
||||||
at: &target
|
at: &target
|
||||||
withName: NULL];
|
withName: NULL];
|
||||||
|
|
||||||
if ([self includesLocalObject:(void*)target]) {
|
[rmc decodeValueOfCType: @encode(typeof(char))
|
||||||
|
at: &vended
|
||||||
|
withName: NULL];
|
||||||
|
|
||||||
|
prox = [self includesLocalObject:(void*)target];
|
||||||
|
if (prox != nil) {
|
||||||
|
if (vended) {
|
||||||
|
[prox setVended];
|
||||||
|
}
|
||||||
[self removeLocalObject: (id)target];
|
[self removeLocalObject: (id)target];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1315,8 +1422,8 @@ static int messages_received_count;
|
||||||
at: &target
|
at: &target
|
||||||
withName: NULL];
|
withName: NULL];
|
||||||
|
|
||||||
if ([self includesLocalObject:(void*)target] == NO) {
|
if ([self includesLocalObject:(void*)target] == nil) {
|
||||||
if ([[self class] includesLocalObject:(void*)target] == YES) {
|
if ([[self class] includesLocalObject:(void*)target] != nil) {
|
||||||
[NSDistantObject proxyWithLocal: (id)target connection: self];
|
[NSDistantObject proxyWithLocal: (id)target connection: self];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1411,6 +1518,7 @@ static int messages_received_count;
|
||||||
at:&type
|
at:&type
|
||||||
withName:@"Requested Method Type for Target"];
|
withName:@"Requested Method Type for Target"];
|
||||||
[op dismiss];
|
[op dismiss];
|
||||||
|
[rmc dismiss];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1436,13 +1544,11 @@ static int messages_received_count;
|
||||||
/* It won't take much time to handle this, so go ahead and service
|
/* It won't take much time to handle this, so go ahead and service
|
||||||
it, even if we are waiting for a reply. */
|
it, even if we are waiting for a reply. */
|
||||||
[conn _service_rootObject: rmc];
|
[conn _service_rootObject: rmc];
|
||||||
[rmc dismiss];
|
|
||||||
break;
|
break;
|
||||||
case METHODTYPE_REQUEST:
|
case METHODTYPE_REQUEST:
|
||||||
/* It won't take much time to handle this, so go ahead and service
|
/* It won't take much time to handle this, so go ahead and service
|
||||||
it, even if we are waiting for a reply. */
|
it, even if we are waiting for a reply. */
|
||||||
[conn _service_typeForSelector: rmc];
|
[conn _service_typeForSelector: rmc];
|
||||||
[rmc dismiss];
|
|
||||||
break;
|
break;
|
||||||
case METHOD_REQUEST:
|
case METHOD_REQUEST:
|
||||||
/* We just got a new request; we need to decide whether to queue
|
/* We just got a new request; we need to decide whether to queue
|
||||||
|
@ -1538,7 +1644,7 @@ static int messages_received_count;
|
||||||
&& [a_rmc sequenceNumber] == sn)
|
&& [a_rmc sequenceNumber] == sn)
|
||||||
{
|
{
|
||||||
if (debug_connection)
|
if (debug_connection)
|
||||||
printf("Getting received reply from queue\n");
|
NSLog(@"Getting received reply from queue\n");
|
||||||
[received_reply_rmc_queue removeObjectAtIndex: i];
|
[received_reply_rmc_queue removeObjectAtIndex: i];
|
||||||
the_rmc = a_rmc;
|
the_rmc = a_rmc;
|
||||||
break;
|
break;
|
||||||
|
@ -1625,6 +1731,9 @@ static int messages_received_count;
|
||||||
NSMapInsert(all_connections_local_targets, (void*)local, counter);
|
NSMapInsert(all_connections_local_targets, (void*)local, counter);
|
||||||
[counter release];
|
[counter release];
|
||||||
}
|
}
|
||||||
|
if (debug_connection > 2)
|
||||||
|
NSLog(@"add local object (0x%x) to connection (0x%x) (ref %d)\n",
|
||||||
|
(unsigned)local, (unsigned) self, [counter value]);
|
||||||
[proxiesHashGate unlock];
|
[proxiesHashGate unlock];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1658,9 +1767,9 @@ static int messages_received_count;
|
||||||
- (void) removeLocalObject: anObj
|
- (void) removeLocalObject: anObj
|
||||||
{
|
{
|
||||||
id counter;
|
id counter;
|
||||||
|
unsigned val = 0;
|
||||||
|
|
||||||
[proxiesHashGate lock];
|
[proxiesHashGate lock];
|
||||||
NSMapRemove (local_targets, (void*)anObj);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If all references to a local proxy have gone - remove the
|
* If all references to a local proxy have gone - remove the
|
||||||
|
@ -1669,15 +1778,40 @@ static int messages_received_count;
|
||||||
counter = NSMapGet(all_connections_local_targets, (void*)anObj);
|
counter = NSMapGet(all_connections_local_targets, (void*)anObj);
|
||||||
if (counter) {
|
if (counter) {
|
||||||
[counter decrement];
|
[counter decrement];
|
||||||
if ([counter value] == 0) {
|
if ((val = [counter value]) == 0) {
|
||||||
|
NSDistantObject *prox = NSMapGet(local_targets, (void*)anObj);
|
||||||
|
|
||||||
NSMapRemove(all_connections_local_targets, (void*)anObj);
|
NSMapRemove(all_connections_local_targets, (void*)anObj);
|
||||||
|
/*
|
||||||
|
* If this proxy has been vended onwards by another process, we
|
||||||
|
* need to keep a reference to the local object around for a
|
||||||
|
* while in case that other process needs it.
|
||||||
|
*/
|
||||||
|
if ([prox isVended]) {
|
||||||
|
id item;
|
||||||
|
if (timer == nil) {
|
||||||
|
timer = [NSTimer scheduledTimerWithTimeInterval: 1.0
|
||||||
|
target: [NSConnection class]
|
||||||
|
selector: @selector(_timeout:)
|
||||||
|
userInfo: nil
|
||||||
|
repeats: YES];
|
||||||
|
}
|
||||||
|
item = [CachedLocalObject itemWithObject: anObj time: 30];
|
||||||
|
NSMapInsert(all_connections_local_cached, anObj, item);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NSMapRemove (local_targets, (void*)anObj);
|
||||||
|
|
||||||
|
if (debug_connection > 2)
|
||||||
|
NSLog(@"remove local object (0x%x) to connection (0x%x) (ref %d)\n",
|
||||||
|
(unsigned)anObj, (unsigned) self, val);
|
||||||
|
|
||||||
[proxiesHashGate unlock];
|
[proxiesHashGate unlock];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) _release_targets: (unsigned int*)list count:(unsigned int)number
|
- (void) _release_targets: (NSDistantObject**)list count:(unsigned int)number
|
||||||
{
|
{
|
||||||
NS_DURING
|
NS_DURING
|
||||||
{
|
{
|
||||||
|
@ -1700,11 +1834,15 @@ static int messages_received_count;
|
||||||
withName: NULL];
|
withName: NULL];
|
||||||
|
|
||||||
for (i = 0; i < number; i++) {
|
for (i = 0; i < number; i++) {
|
||||||
unsigned int target = list[i];
|
unsigned target = (unsigned)[list[i] targetForProxy];
|
||||||
|
char vended = [list[i] isVended];
|
||||||
|
|
||||||
[op encodeValueOfCType: @encode(typeof(target))
|
[op encodeValueOfCType: @encode(typeof(target))
|
||||||
at: &target
|
at: &target
|
||||||
withName: NULL];
|
withName: NULL];
|
||||||
|
[op encodeValueOfCType: @encode(char)
|
||||||
|
at: &vended
|
||||||
|
withName: NULL];
|
||||||
}
|
}
|
||||||
|
|
||||||
[op dismiss];
|
[op dismiss];
|
||||||
|
@ -1713,8 +1851,7 @@ static int messages_received_count;
|
||||||
NS_HANDLER
|
NS_HANDLER
|
||||||
{
|
{
|
||||||
if (debug_connection)
|
if (debug_connection)
|
||||||
fprintf (stderr, "failed to release targets - %s\n",
|
NSLog(@"failed to release targets - %@\n", [localException name]);
|
||||||
[[localException name] cStringNoCopy]);
|
|
||||||
}
|
}
|
||||||
NS_ENDHANDLER
|
NS_ENDHANDLER
|
||||||
}
|
}
|
||||||
|
@ -1730,10 +1867,11 @@ static int messages_received_count;
|
||||||
if (receive_port && is_valid) {
|
if (receive_port && is_valid) {
|
||||||
id op;
|
id op;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
int seq_num = [self _newMsgNumber];
|
||||||
|
|
||||||
op = [[self encodingClass]
|
op = [[self encodingClass]
|
||||||
newForWritingWithConnection: self
|
newForWritingWithConnection: self
|
||||||
sequenceNumber: [self _newMsgNumber]
|
sequenceNumber: seq_num
|
||||||
identifier: PROXY_RETAIN];
|
identifier: PROXY_RETAIN];
|
||||||
|
|
||||||
[op encodeValueOfCType: @encode(typeof(target))
|
[op encodeValueOfCType: @encode(typeof(target))
|
||||||
|
@ -1746,8 +1884,7 @@ static int messages_received_count;
|
||||||
NS_HANDLER
|
NS_HANDLER
|
||||||
{
|
{
|
||||||
if (debug_connection)
|
if (debug_connection)
|
||||||
fprintf (stderr, "failed to retain target - %s\n",
|
NSLog(@"failed to retain target - %@\n", [localException name]);
|
||||||
[[localException name] cStringNoCopy]);
|
|
||||||
}
|
}
|
||||||
NS_ENDHANDLER
|
NS_ENDHANDLER
|
||||||
}
|
}
|
||||||
|
@ -1766,7 +1903,7 @@ static int messages_received_count;
|
||||||
* Tell the remote application that we have removed our proxy and
|
* Tell the remote application that we have removed our proxy and
|
||||||
* it can release it's local object.
|
* it can release it's local object.
|
||||||
*/
|
*/
|
||||||
[self _release_targets:&target count:1];
|
[self _release_targets:&aProxy count:1];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id <Collecting>) localObjects
|
- (id <Collecting>) localObjects
|
||||||
|
@ -1818,24 +1955,24 @@ static int messages_received_count;
|
||||||
[proxiesHashGate unlock];
|
[proxiesHashGate unlock];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL) includesProxyForTarget: (unsigned)target
|
- (id) includesProxyForTarget: (void*)target
|
||||||
{
|
{
|
||||||
BOOL ret;
|
NSDistantObject *ret;
|
||||||
|
|
||||||
/* Don't assert (is_valid); */
|
/* Don't assert (is_valid); */
|
||||||
[proxiesHashGate lock];
|
[proxiesHashGate lock];
|
||||||
ret = NSMapGet (remote_proxies, (void*)target) ? YES : NO;
|
ret = NSMapGet (remote_proxies, (void*)target);
|
||||||
[proxiesHashGate unlock];
|
[proxiesHashGate unlock];
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL) includesLocalObject: anObj
|
- (id) includesLocalObject: anObj
|
||||||
{
|
{
|
||||||
BOOL ret;
|
NSDistantObject* ret;
|
||||||
|
|
||||||
/* Don't assert (is_valid); */
|
/* Don't assert (is_valid); */
|
||||||
[proxiesHashGate lock];
|
[proxiesHashGate lock];
|
||||||
ret = NSMapGet (local_targets, (void*)anObj) ? YES : NO;
|
ret = NSMapGet(local_targets, (void*)anObj);
|
||||||
[proxiesHashGate unlock];
|
[proxiesHashGate unlock];
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1846,14 +1983,17 @@ static int messages_received_count;
|
||||||
for the Proxy to check the Proxy's connection only (using
|
for the Proxy to check the Proxy's connection only (using
|
||||||
-includesLocalObject), because the proxy may have come from a
|
-includesLocalObject), because the proxy may have come from a
|
||||||
triangle connection. */
|
triangle connection. */
|
||||||
+ (BOOL) includesLocalObject: anObj
|
+ (id) includesLocalObject: anObj
|
||||||
{
|
{
|
||||||
BOOL ret;
|
id ret;
|
||||||
|
|
||||||
/* Don't assert (is_valid); */
|
/* Don't assert (is_valid); */
|
||||||
NSParameterAssert (all_connections_local_targets);
|
NSParameterAssert (all_connections_local_targets);
|
||||||
[proxiesHashGate lock];
|
[proxiesHashGate lock];
|
||||||
ret = NSMapGet (all_connections_local_targets, (void*)anObj) ? YES : NO;
|
ret = NSMapGet (all_connections_local_targets, (void*)anObj);
|
||||||
|
if (ret == nil) {
|
||||||
|
ret = NSMapGet (all_connections_local_cached, (void*)anObj);
|
||||||
|
}
|
||||||
[proxiesHashGate unlock];
|
[proxiesHashGate unlock];
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -2000,9 +2140,9 @@ static int messages_received_count;
|
||||||
id port = [notification object];
|
id port = [notification object];
|
||||||
|
|
||||||
if (debug_connection)
|
if (debug_connection)
|
||||||
fprintf (stderr, "Received port invalidation notification for "
|
NSLog(@"Received port invalidation notification for "
|
||||||
"connection 0x%x\n\t%s\n", (unsigned)self,
|
@"connection 0x%x\n\t%@\n", (unsigned)self,
|
||||||
[[port description] cStringNoCopy]);
|
[port description]);
|
||||||
|
|
||||||
/* 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
|
||||||
|
|
|
@ -28,6 +28,17 @@
|
||||||
|
|
||||||
static int debug_proxy;
|
static int debug_proxy;
|
||||||
|
|
||||||
|
@interface NSDistantObject (Debug)
|
||||||
|
+ (void) setDebug: (int)val;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation NSDistantObject (Debug)
|
||||||
|
+ (void) setDebug: (int)val
|
||||||
|
{
|
||||||
|
debug_proxy = val;
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
@implementation NSDistantObject
|
@implementation NSDistantObject
|
||||||
|
|
||||||
/* This is the proxy tag; it indicates where the local object is,
|
/* This is the proxy tag; it indicates where the local object is,
|
||||||
|
@ -127,8 +138,7 @@ format: @"NSDistantObject objects only encode with PortEncoder class"];
|
||||||
proxy_tag = PROXY_LOCAL_FOR_SENDER;
|
proxy_tag = PROXY_LOCAL_FOR_SENDER;
|
||||||
|
|
||||||
if (debug_proxy)
|
if (debug_proxy)
|
||||||
fprintf(stderr, "Sending a proxy, will be remote 0x%x "
|
NSLog(@"Sending a proxy, will be remote 0x%x connection 0x%x\n",
|
||||||
"connection 0x%x\n",
|
|
||||||
(unsigned)_object,
|
(unsigned)_object,
|
||||||
(unsigned)_connection);
|
(unsigned)_connection);
|
||||||
|
|
||||||
|
@ -147,8 +157,7 @@ format: @"NSDistantObject objects only encode with PortEncoder class"];
|
||||||
proxy_tag = PROXY_LOCAL_FOR_RECEIVER;
|
proxy_tag = PROXY_LOCAL_FOR_RECEIVER;
|
||||||
|
|
||||||
if (debug_proxy)
|
if (debug_proxy)
|
||||||
fprintf(stderr, "Sending a proxy, will be local 0x%x "
|
NSLog(@"Sending a proxy, will be local 0x%x connection 0x%x\n",
|
||||||
"connection 0x%x\n",
|
|
||||||
(unsigned)_object,
|
(unsigned)_object,
|
||||||
(unsigned)_connection);
|
(unsigned)_connection);
|
||||||
|
|
||||||
|
@ -174,8 +183,8 @@ format: @"NSDistantObject objects only encode with PortEncoder class"];
|
||||||
proxy_tag = PROXY_REMOTE_FOR_BOTH;
|
proxy_tag = PROXY_REMOTE_FOR_BOTH;
|
||||||
|
|
||||||
if (debug_proxy)
|
if (debug_proxy)
|
||||||
fprintf(stderr, "Sending triangle-connection proxy 0x%x "
|
NSLog(@"Sending triangle-connection proxy 0x%x "
|
||||||
"proxy-conn 0x%x to-conn 0x%x\n",
|
@"proxy-conn 0x%x to-conn 0x%x\n",
|
||||||
(unsigned)_object,
|
(unsigned)_object,
|
||||||
(unsigned)_connection, (unsigned)encoder_connection);
|
(unsigned)_connection, (unsigned)encoder_connection);
|
||||||
|
|
||||||
|
@ -193,6 +202,10 @@ format: @"NSDistantObject objects only encode with PortEncoder class"];
|
||||||
|
|
||||||
[aRmc encodeBycopyObject: proxy_connection_out_port
|
[aRmc encodeBycopyObject: proxy_connection_out_port
|
||||||
withName: @"Proxy outPort"];
|
withName: @"Proxy outPort"];
|
||||||
|
/*
|
||||||
|
* Make a note that we have passed this on to another process.
|
||||||
|
*/
|
||||||
|
_isVended = YES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,7 +257,7 @@ format: @"NSDistantObject objects only encode with PortEncoder class"];
|
||||||
[_connection addLocalObject: self];
|
[_connection addLocalObject: self];
|
||||||
|
|
||||||
if (debug_proxy)
|
if (debug_proxy)
|
||||||
printf("Created new local=0x%x object 0x%x connection 0x%x\n",
|
NSLog(@"Created new local=0x%x object 0x%x connection 0x%x\n",
|
||||||
(unsigned)self, (unsigned)_object, (unsigned)_connection);
|
(unsigned)self, (unsigned)_object, (unsigned)_connection);
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
@ -280,7 +293,7 @@ format: @"NSDistantObject objects only encode with PortEncoder class"];
|
||||||
[_connection addProxy: self];
|
[_connection addProxy: self];
|
||||||
|
|
||||||
if (debug_proxy)
|
if (debug_proxy)
|
||||||
printf("Created new proxy=0x%x object 0x%x connection 0x%x\n",
|
NSLog(@"Created new proxy=0x%x object 0x%x connection 0x%x\n",
|
||||||
(unsigned)self, (unsigned)_object, (unsigned)_connection);
|
(unsigned)self, (unsigned)_object, (unsigned)_connection);
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
@ -370,8 +383,8 @@ format: @"NSDistantObject objects only decode with PortDecoder class"];
|
||||||
withName: NULL];
|
withName: NULL];
|
||||||
|
|
||||||
if (debug_proxy)
|
if (debug_proxy)
|
||||||
fprintf(stderr, "Receiving a proxy for local object 0x%x "
|
NSLog(@"Receiving a proxy for local object 0x%x "
|
||||||
"connection 0x%x\n", target, (unsigned)decoder_connection);
|
@"connection 0x%x\n", target, (unsigned)decoder_connection);
|
||||||
|
|
||||||
if (![[decoder_connection class] includesLocalObject: (id)target])
|
if (![[decoder_connection class] includesLocalObject: (id)target])
|
||||||
[NSException raise: @"ProxyDecodedBadTarget"
|
[NSException raise: @"ProxyDecodedBadTarget"
|
||||||
|
@ -381,6 +394,9 @@ format: @"NSDistantObject objects only decode with PortDecoder class"];
|
||||||
id local = [NSDistantObject proxyWithLocal: (id)target
|
id local = [NSDistantObject proxyWithLocal: (id)target
|
||||||
connection: decoder_connection];
|
connection: decoder_connection];
|
||||||
|
|
||||||
|
if (debug_proxy)
|
||||||
|
NSLog(@"Local object is 0x%x (0x%x)\n",
|
||||||
|
(unsigned)local, (unsigned)[local targetForProxy]);
|
||||||
return [[local targetForProxy] retain];
|
return [[local targetForProxy] retain];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,7 +412,7 @@ format: @"NSDistantObject objects only decode with PortDecoder class"];
|
||||||
at: &target
|
at: &target
|
||||||
withName: NULL];
|
withName: NULL];
|
||||||
if (debug_proxy)
|
if (debug_proxy)
|
||||||
fprintf(stderr, "Receiving a proxy, was local 0x%x connection 0x%x\n",
|
NSLog(@"Receiving a proxy, was local 0x%x connection 0x%x\n",
|
||||||
(unsigned)target, (unsigned)decoder_connection);
|
(unsigned)target, (unsigned)decoder_connection);
|
||||||
return [[NSDistantObject proxyWithTarget: (id)target
|
return [[NSDistantObject proxyWithTarget: (id)target
|
||||||
connection: decoder_connection] retain];
|
connection: decoder_connection] retain];
|
||||||
|
@ -453,8 +469,8 @@ format: @"NSDistantObject objects only decode with PortDecoder class"];
|
||||||
ancestorConnection: decoder_connection];
|
ancestorConnection: decoder_connection];
|
||||||
|
|
||||||
if (debug_proxy)
|
if (debug_proxy)
|
||||||
fprintf(stderr, "Receiving a triangle-connection proxy 0x%x "
|
NSLog(@"Receiving a triangle-connection proxy 0x%x "
|
||||||
"connection 0x%x\n", target, (unsigned)proxy_connection);
|
@"connection 0x%x\n", target, (unsigned)proxy_connection);
|
||||||
|
|
||||||
assert (proxy_connection != decoder_connection);
|
assert (proxy_connection != decoder_connection);
|
||||||
assert ([proxy_connection isValid]);
|
assert ([proxy_connection isValid]);
|
||||||
|
@ -511,7 +527,7 @@ format: @"NSDistantObject objects only decode with PortDecoder class"];
|
||||||
- forward: (SEL)aSel :(arglist_t)frame
|
- forward: (SEL)aSel :(arglist_t)frame
|
||||||
{
|
{
|
||||||
if (debug_proxy)
|
if (debug_proxy)
|
||||||
printf("NSDistantObject forwarding %s\n", sel_get_name(aSel));
|
NSLog(@"NSDistantObject forwarding %s\n", sel_get_name(aSel));
|
||||||
|
|
||||||
if (![_connection isValid])
|
if (![_connection isValid])
|
||||||
[NSException
|
[NSException
|
||||||
|
|
|
@ -96,6 +96,17 @@ static int debug_tcp_port = 0;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
@interface NSPort (Debug)
|
||||||
|
+ (void) setDebug: (int)val;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation NSPort (Debug)
|
||||||
|
+ (void) setDebug: (int)val
|
||||||
|
{
|
||||||
|
debug_tcp_port = val;
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
/* Private interfaces */
|
/* Private interfaces */
|
||||||
|
|
||||||
|
@ -997,10 +1008,8 @@ static NSMapTable* port_number_2_port;
|
||||||
[self _addClientOutPort: op];
|
[self _addClientOutPort: op];
|
||||||
[op release];
|
[op release];
|
||||||
if (debug_tcp_port)
|
if (debug_tcp_port)
|
||||||
fprintf (stderr,
|
NSLog(@"%s: Accepted connection from\n %@.\n",
|
||||||
"%s: Accepted connection from\n %s.\n",
|
object_get_class_name (self), [op description]);
|
||||||
object_get_class_name (self),
|
|
||||||
[[op description] cString]);
|
|
||||||
[NotificationDispatcher
|
[NotificationDispatcher
|
||||||
postNotificationName: InPortAcceptedClientNotification
|
postNotificationName: InPortAcceptedClientNotification
|
||||||
object: self
|
object: self
|
||||||
|
@ -1074,6 +1083,9 @@ static NSMapTable* port_number_2_port;
|
||||||
the packet is complete; return it. */
|
the packet is complete; return it. */
|
||||||
assert (packet && [packet class]);
|
assert (packet && [packet class]);
|
||||||
NSMapRemove(_client_sock_2_packet, (void*)fd_index);
|
NSMapRemove(_client_sock_2_packet, (void*)fd_index);
|
||||||
|
if (debug_tcp_port > 1)
|
||||||
|
NSLog(@"%s: Read from socket %d\n",
|
||||||
|
object_get_class_name (self), fd_index);
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1161,10 +1173,8 @@ assert(type == ET_RPORT);
|
||||||
|
|
||||||
assert (is_valid);
|
assert (is_valid);
|
||||||
if (debug_tcp_port)
|
if (debug_tcp_port)
|
||||||
fprintf (stderr,
|
NSLog(@"%s: Closed connection from\n %@\n",
|
||||||
"%s: Closed connection from\n %s\n",
|
object_get_class_name (self), [p description]);
|
||||||
object_get_class_name (self),
|
|
||||||
[[p description] cString]);
|
|
||||||
|
|
||||||
packet = NSMapGet (_client_sock_2_packet, (void*)s);
|
packet = NSMapGet (_client_sock_2_packet, (void*)s);
|
||||||
if (packet)
|
if (packet)
|
||||||
|
@ -1453,8 +1463,8 @@ static NSMapTable *out_port_bag = NULL;
|
||||||
sockaddr,
|
sockaddr,
|
||||||
sizeof (p->_remote_in_port_address));
|
sizeof (p->_remote_in_port_address));
|
||||||
if (debug_tcp_port)
|
if (debug_tcp_port)
|
||||||
printf ("TcpOutPort setting remote address\n%s\n",
|
NSLog(@"TcpOutPort setting remote address\n%@\n",
|
||||||
[[self description] cString]);
|
[self description]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (p)
|
if (p)
|
||||||
|
@ -1803,7 +1813,7 @@ static NSMapTable *out_port_bag = NULL;
|
||||||
count: sizeof (_remote_in_port_address.sin_addr.s_addr)
|
count: sizeof (_remote_in_port_address.sin_addr.s_addr)
|
||||||
withName: @"inet address"];
|
withName: @"inet address"];
|
||||||
if (debug_tcp_port)
|
if (debug_tcp_port)
|
||||||
printf ("TcpOutPort encoded port %hd host %s\n",
|
NSLog(@"TcpOutPort encoded port %hd host %s\n",
|
||||||
ntohs (_remote_in_port_address.sin_port),
|
ntohs (_remote_in_port_address.sin_port),
|
||||||
inet_ntoa (_remote_in_port_address.sin_addr));
|
inet_ntoa (_remote_in_port_address.sin_addr));
|
||||||
}
|
}
|
||||||
|
@ -1820,7 +1830,7 @@ static NSMapTable *out_port_bag = NULL;
|
||||||
count: sizeof (addr.sin_addr.s_addr)
|
count: sizeof (addr.sin_addr.s_addr)
|
||||||
withName: NULL];
|
withName: NULL];
|
||||||
if (debug_tcp_port)
|
if (debug_tcp_port)
|
||||||
printf ("TcpOutPort decoded port %hd host %s\n",
|
NSLog(@"TcpOutPort decoded port %hd host %s\n",
|
||||||
ntohs (addr.sin_port),
|
ntohs (addr.sin_port),
|
||||||
inet_ntoa (addr.sin_addr));
|
inet_ntoa (addr.sin_addr));
|
||||||
return [TcpOutPort newForSendingToSockaddr: &addr
|
return [TcpOutPort newForSendingToSockaddr: &addr
|
||||||
|
@ -1938,6 +1948,9 @@ static NSMapTable *out_port_bag = NULL;
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
|
if (debug_tcp_port > 1)
|
||||||
|
NSLog(@"%s: Write to socket %d\n", object_get_class_name (self), s);
|
||||||
|
|
||||||
/* Put the packet size in the first four bytes of the packet. */
|
/* Put the packet size in the first four bytes of the packet. */
|
||||||
assert (prefix == PREFIX_SIZE);
|
assert (prefix == PREFIX_SIZE);
|
||||||
*(PREFIX_LENGTH_TYPE*)[data mutableBytes] = htonl (eof_position);
|
*(PREFIX_LENGTH_TYPE*)[data mutableBytes] = htonl (eof_position);
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
#define NSSTRING 257
|
|
||||||
#define NSDATA 258
|
|
||||||
#define ERROR 259
|
|
||||||
typedef union {
|
typedef union {
|
||||||
id obj;
|
id obj;
|
||||||
} YYSTYPE;
|
} YYSTYPE;
|
||||||
|
#define NSSTRING 258
|
||||||
|
#define NSDATA 259
|
||||||
|
#define ERROR 260
|
||||||
|
|
||||||
|
|
||||||
extern YYSTYPE pllval;
|
extern YYSTYPE pllval;
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,9 +1,11 @@
|
||||||
#define QUOTED 257
|
|
||||||
#define LABEL 258
|
|
||||||
#define SEMICOLEN 259
|
|
||||||
#define EQUALS 260
|
|
||||||
#define ERROR 261
|
|
||||||
typedef union {
|
typedef union {
|
||||||
id obj;
|
id obj;
|
||||||
} YYSTYPE;
|
} YYSTYPE;
|
||||||
|
#define QUOTED 258
|
||||||
|
#define LABEL 259
|
||||||
|
#define SEMICOLEN 260
|
||||||
|
#define EQUALS 261
|
||||||
|
#define ERROR 262
|
||||||
|
|
||||||
|
|
||||||
extern YYSTYPE sflval;
|
extern YYSTYPE sflval;
|
||||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue