From dae20769ac858575fce0fe3b6d78749240b3248c Mon Sep 17 00:00:00 2001 From: richard Date: Sun, 2 Jul 2000 18:57:05 +0000 Subject: [PATCH] DO and encoding updates git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@6861 72102866-910b-0410-8b05-ffd578937521 --- ChangeLog | 14 ++ Source/GSConnection.m | 284 +++++++++++++++++++++----------------- Source/GSPortCoder.m | 18 ++- Source/GSTcpPort.m | 19 +-- Source/NSArchiver.m | 7 +- Source/NSData.m | 49 +++---- Source/NSDistantObject.m | 30 +++- Source/NSInvocation.m | 1 + Source/NSPort.m | 32 ++++- Source/NSPortNameServer.m | 1 + Testing/client.m | 23 +-- Testing/server.m | 11 +- 12 files changed, 285 insertions(+), 204 deletions(-) diff --git a/ChangeLog b/ChangeLog index 787f06cba..79b500a1e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2000-07-02 Richard Frith-Macdonald + + * Source/GSConnection.m: Implementation almost complete + * Source/GSPortCoder.m: Completed + * Source/GSTcpPort.m: tidied for MacOS-X compatibility + * Source/NSArchiver.m: Bugfix encoding structures containing arrays + * Source/NSData.m: minor tidy + * Source/NSDistantObject.m: update for new implementation + * Source/NSInvocation.m: bugfix decoding + * Source/NSPort.m: update for MacOS-X complience + * Source/NSPortNameServer.m: tidied + * Testing/client.m: Update + * Testing/server.m: update + 2000-06-30 Adam Fedor libgstep-base now compiles (and links) into a DLL on Cygwin. diff --git a/Source/GSConnection.m b/Source/GSConnection.m index 50fa03b3e..1066a5aa3 100644 --- a/Source/GSConnection.m +++ b/Source/GSConnection.m @@ -30,9 +30,9 @@ #include #include -#include #include -#include +#include + #include #include #include @@ -49,6 +49,12 @@ #include #include #include +#include + +#define F_LOCK(X) {NSDebugFLLog(@"GSConnection",@"Lock %@",X);[X lock];} +#define F_UNLOCK(X) {NSDebugFLLog(@"GSConnection",@"Unlock %@",X);[X unlock];} +#define M_LOCK(X) {NSDebugMLLog(@"GSConnection",@"Lock %@",X);[X lock];} +#define M_UNLOCK(X) {NSDebugMLLog(@"GSConnection",@"Unlock %@",X);[X unlock];} static NSString* stringFromMsgType(int type) @@ -231,7 +237,7 @@ existingConnection(NSPort *receivePort, NSPort *sendPort) NSHashEnumerator enumerator; NSConnection *c; - [connection_table_gate lock]; + F_LOCK(connection_table_gate); enumerator = NSEnumerateHashTable(connection_table); while ((c = (NSConnection*)NSNextHashEnumeratorItem(&enumerator)) != nil) { @@ -246,7 +252,7 @@ existingConnection(NSPort *receivePort, NSPort *sendPort) break; } } - [connection_table_gate unlock]; + F_UNLOCK(connection_table_gate); return c; } @@ -258,9 +264,9 @@ rootObjectForInPort(NSPort *aPort) { id rootObject; - [root_object_map_gate lock]; + F_LOCK(root_object_map_gate); rootObject = (id)NSMapGet(root_object_map, (void*)(gsaddr)aPort); - [root_object_map_gate unlock]; + F_UNLOCK(root_object_map_gate); return rootObject; } @@ -270,7 +276,7 @@ setRootObjectForInPort(id anObj, NSPort *aPort) { id oldRootObject; - [root_object_map_gate lock]; + F_LOCK(root_object_map_gate); oldRootObject = (id)NSMapGet(root_object_map, (void*)(gsaddr)aPort); if (oldRootObject != anObj) { @@ -284,7 +290,7 @@ setRootObjectForInPort(id anObj, NSPort *aPort) NSMapRemove(root_object_map, (void*)(gsaddr)aPort); } } - [root_object_map_gate unlock]; + F_UNLOCK(root_object_map_gate); } static NSMapTable *all_connections_local_objects = NULL; @@ -318,7 +324,7 @@ static int messages_received_count; if (c == nil) { c = [self allocWithZone: NSDefaultMallocZone()]; - c = [self initWithReceivePort: r sendPort: s]; + c = [c initWithReceivePort: r sendPort: s]; AUTORELEASE(c); } return c; @@ -496,7 +502,7 @@ static int messages_received_count; - (void) addRequestMode: (NSString*)mode { - [_refGate lock]; + M_LOCK(_refGate); if ([self isValid] == YES) { if ([_requestModes containsObject: mode] == NO) @@ -512,12 +518,12 @@ static int messages_received_count; [_requestModes addObject: mode]; } } - [_refGate unlock]; + M_UNLOCK(_refGate); } - (void) addRunLoop: (NSRunLoop*)loop { - [_refGate lock]; + M_LOCK(_refGate); if ([self isValid] == YES) { if ([_runLoops indexOfObjectIdenticalTo: loop] == NSNotFound) @@ -533,7 +539,7 @@ static int messages_received_count; [_runLoops addObject: loop]; } } - [_refGate unlock]; + M_UNLOCK(_refGate); } - (void) dealloc @@ -600,18 +606,16 @@ static int messages_received_count; s = r; } - [connection_table_gate lock]; + conn = existingConnection(r, s); /* * If the send and receive ports match an existing connection * deallocate the new one and retain and return the old one. */ - conn = existingConnection(r, s); if (conn != nil) { RELEASE(self); self = RETAIN(conn); - [connection_table_gate unlock]; if (debug_connection > 2) { NSLog(@"Found existing connection (0x%x) for \n\t%@\n\t%@", @@ -620,11 +624,20 @@ static int messages_received_count; return self; } + /* + * The parent connection is the one whose send and receive ports are + * both the same as our receive port. + */ + parent = existingConnection(r, r); + if (debug_connection) { - NSLog(@"Initialising new connection 0x%x\n\t%@\n\t%@", - (gsaddr)self, r, s); + NSLog(@"Initialising new connection with parent 0x%x, 0x%x\n\t%@\n\t%@", + (gsaddr)parent, (gsaddr)self, r, s); } + + M_LOCK(connection_table_gate); + _isValid = YES; _receivePort = RETAIN(r); _sendPort = RETAIN(s); @@ -674,7 +687,6 @@ static int messages_received_count; /* * Some attributes are inherited from the parent if possible. */ - parent = existingConnection(r, r); if (parent != nil) { _independentQueueing = parent->_independentQueueing; @@ -710,7 +722,7 @@ static int messages_received_count; { if ([del connection: parent shouldMakeNewConnection: self] == NO) { - [connection_table_gate unlock]; + M_UNLOCK(connection_table_gate); RELEASE(self); return nil; } @@ -720,7 +732,7 @@ static int messages_received_count; { if (![del makeNewConnection: self sender: parent]) { - [connection_table_gate unlock]; + M_UNLOCK(connection_table_gate); RELEASE(self); return nil; } @@ -731,6 +743,15 @@ static int messages_received_count; if ([del respondsTo: @selector(connection:didConnect:)]) self = [del connection: parent didConnect: self]; + /* + * If we have no parent, we must handle incoming packets on our + * receive port ourself - so we set ourself up as the port delegate. + */ + if (parent == nil) + { + [_receivePort setDelegate: self]; + } + /* Register ourselves for invalidation notification when the ports become invalid. */ nCenter = [NSNotificationCenter defaultCenter]; @@ -748,7 +769,7 @@ static int messages_received_count; 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]; + M_UNLOCK(connection_table_gate); [[NSNotificationCenter defaultCenter] postNotificationName: NSConnectionDidInitializeNotification @@ -761,10 +782,10 @@ static int messages_received_count; { BOOL wasValid; - [_refGate lock]; + M_LOCK(_refGate); wasValid = _isValid; _isValid = NO; - [_refGate unlock]; + M_UNLOCK(_refGate); if (wasValid == NO) { @@ -814,7 +835,7 @@ static int messages_received_count; NSArray *targets; unsigned i; - [_proxiesGate lock]; + M_LOCK(_proxiesGate); targets = NSAllMapTableValues(_localTargets); IF_NO_GC(RETAIN(targets)); for (i = 0; i < [targets count]; i++) @@ -824,7 +845,7 @@ static int messages_received_count; [self removeLocalObject: t]; } [targets release]; - [_proxiesGate unlock]; + M_UNLOCK(_proxiesGate); } RELEASE(self); @@ -840,9 +861,9 @@ static int messages_received_count; NSArray *c; /* Don't assert (_isValid); */ - [_proxiesGate lock]; + M_LOCK(_proxiesGate); c = NSAllMapTableValues(_localObjects); - [_proxiesGate unlock]; + M_UNLOCK(_proxiesGate); return c; } @@ -913,15 +934,15 @@ static int messages_received_count; NSArray *c; /* Don't assert (_isValid); */ - [_proxiesGate lock]; + M_LOCK(_proxiesGate); c = NSAllMapTableValues(_remoteProxies); - [_proxiesGate unlock]; + M_UNLOCK(_proxiesGate); return c; } - (void) removeRequestMode: (NSString*)mode { - [_refGate lock]; + M_LOCK(_refGate); if ([_requestModes containsObject: mode]) { unsigned c = [_runLoops count]; @@ -934,14 +955,14 @@ static int messages_received_count; } [_requestModes removeObject: mode]; } - [_refGate unlock]; + M_UNLOCK(_refGate); } - (void) removeRunLoop: (NSRunLoop*)loop { unsigned pos; - [_refGate lock]; + M_LOCK(_refGate); pos = [_runLoops indexOfObjectIdenticalTo: loop]; if (pos != NSNotFound) { @@ -955,7 +976,7 @@ static int messages_received_count; } [_runLoops removeObjectAtIndex: pos]; } - [_refGate unlock]; + M_UNLOCK(_refGate); } - (NSTimeInterval) replyTimeout @@ -1028,7 +1049,7 @@ static int messages_received_count; - (void) setRequestMode: (NSString*)mode { - [_refGate lock]; + M_LOCK(_refGate); while ([_requestModes count] > 0 && [_requestModes objectAtIndex: 0] != mode) { [self removeRequestMode: [_requestModes objectAtIndex: 0]]; @@ -1041,7 +1062,7 @@ static int messages_received_count; { [self addRequestMode: mode]; } - [_refGate unlock]; + M_UNLOCK(_refGate); } - (void) setRequestTimeout: (NSTimeInterval)to @@ -1061,7 +1082,7 @@ static int messages_received_count; d = [NSMutableDictionary dictionaryWithCapacity: 8]; - [_refGate lock]; + M_LOCK(_refGate); /* * These are in OPENSTEP 4.2 @@ -1082,12 +1103,12 @@ static int messages_received_count; [d setObject: o forKey: NSConnectionLocalCount]; o = [NSNumber numberWithUnsignedInt: NSCountMapTable(_remoteProxies)]; [d setObject: o forKey: NSConnectionProxyCount]; - [received_request_rmc_queue_gate lock]; + M_LOCK(received_request_rmc_queue_gate); o = [NSNumber numberWithUnsignedInt: [received_request_rmc_queue count]]; - [received_request_rmc_queue_gate unlock]; + M_UNLOCK(received_request_rmc_queue_gate); [d setObject: o forKey: @"Pending packets"]; - [_refGate unlock]; + M_UNLOCK(_refGate); return d; } @@ -1106,11 +1127,11 @@ static int messages_received_count; NSLog(@"finalising 0x%x", (gsaddr)self); [self invalidate]; - [connection_table_gate lock]; + M_LOCK(connection_table_gate); NSHashRemove(connection_table, self); [timer invalidate]; timer = nil; - [connection_table_gate unlock]; + M_UNLOCK(connection_table_gate); /* Remove rootObject from root_object_map if this is last connection */ if (_receivePort != nil && existingConnection(_receivePort, nil) == nil) @@ -1124,11 +1145,24 @@ static int messages_received_count; DESTROY(_requestModes); DESTROY(_runLoops); - /* Finished with ports - releasing them may generate a notification */ + /* + * Finished with ports - releasing them may generate a notification + * If we are the receive port delagate, try to shift responsibility. + */ + if ([_receivePort delegate] == self) + { + NSConnection *root = existingConnection(_receivePort, _receivePort); + + if (root == nil) + { + root = existingConnection(_receivePort, nil); + } + [_receivePort setDelegate: root]; + } DESTROY(_receivePort); DESTROY(_sendPort); - [_proxiesGate lock]; + M_LOCK(_proxiesGate); if (_remoteProxies != 0) { NSFreeMapTable(_remoteProxies); @@ -1144,7 +1178,7 @@ static int messages_received_count; NSFreeMapTable(_localTargets); _localTargets = 0; } - [_proxiesGate unlock]; + M_UNLOCK(_proxiesGate); DESTROY(_requestQueue); if (_replyMap != 0) @@ -1246,14 +1280,15 @@ static int messages_received_count; void decoder(int argnum, void *datum, const char *type, int flags) { - if (type == 0) { - if (ip) { - /* this must be here to avoid trashing alloca'ed retframe */ - [ip dismiss]; - ip = (id)-1; + if (type == 0) + { + if (ip != nil) + { + /* this must be here to avoid trashing alloca'ed retframe */ + ip = (id)-1; + } + return; } - return; - } /* If we didn't get the reply packet yet, get it now. */ if (!ip) { @@ -1273,7 +1308,6 @@ static int messages_received_count; /* Decode the exception object, and raise it. */ id exc; [ip decodeValueOfObjCType: @encode(id) at: &exc]; - [ip dismiss]; ip = (id)-1; /* xxx Is there anything else to clean up in dissect_method_return()? */ @@ -1285,14 +1319,13 @@ static int messages_received_count; for char*'s. We need to make sure it gets freed eventually so we don't have a memory leak. Request here that it be autorelease'ed. Also autorelease created objects. */ - if (*type == _C_CHARPTR) + if ((*type == _C_CHARPTR || *type == _C_PTR) && *(void**)datum != 0) [NSData dataWithBytesNoCopy: *(void**)datum length: 1]; else if (*type == _C_ID) - [*(id*)datum autorelease]; + AUTORELEASE(*(id*)datum); } - retframe = mframe_build_return (argframe, type, out_parameters, - decoder); + retframe = mframe_build_return (argframe, type, out_parameters, decoder); /* Make sure we processed all arguments, and dismissed the IP. IP is always set to -1 after being dismissed; the only places this is done is in this function DECODER(). IP will be nil @@ -1342,7 +1375,7 @@ static int messages_received_count; NSHashEnumerator enumerator; NSConnection *o; - [connection_table_gate lock]; + M_LOCK(connection_table_gate); enumerator = NSEnumerateHashTable(connection_table); while ((o = (NSConnection*)NSNextHashEnumeratorItem(&enumerator)) != nil) { @@ -1351,7 +1384,7 @@ static int messages_received_count; count++; } } - [connection_table_gate unlock]; + M_UNLOCK(connection_table_gate); return count; } @@ -1371,18 +1404,16 @@ static int messages_received_count; NSMutableArray *components = [msg _components]; NSPort *rp = [msg receivePort]; NSPort *sp = [msg sendPort]; - NSConnection *conn = existingConnection(rp, sp); + NSConnection *conn; if (debug_connection > 4) { NSLog(@"handling packet of type %d (%@)", type, stringFromMsgType(type)); } + conn = [NSConnection connectionWithReceivePort: rp sendPort: sp]; if (conn == nil) { - if (debug_connection) - { - NSLog(@"received port message for unknown connection - %@", msg); - } + NSLog(@"received port message for unknown connection - %@", msg); return; } else if ([conn isValid] == NO) @@ -1435,13 +1466,13 @@ static int messages_received_count; * If REPLY_DEPTH is non-zero, we may still want to service it now * if independent_queuing is NO. */ - [conn->_queueGate lock]; + M_LOCK(conn->_queueGate); if (conn->_requestDepth == 0 || conn->_independentQueueing == NO) { conn->_requestDepth++; - [conn->_queueGate unlock]; + M_UNLOCK(conn->_queueGate); [conn _service_forwardForProxy: rmc]; - [conn->_queueGate lock]; + M_LOCK(conn->_queueGate); conn->_requestDepth--; } else @@ -1457,12 +1488,12 @@ static int messages_received_count; rmc = [conn->_requestQueue objectAtIndex: 0]; RETAIN(rmc); [conn->_requestQueue removeObjectAtIndex: 0]; - [conn->_queueGate unlock]; + M_UNLOCK(conn->_queueGate); [conn _service_forwardForProxy: rmc]; - [conn->_queueGate lock]; + M_LOCK(conn->_queueGate); RELEASE(rmc); } - [conn->_queueGate unlock]; + M_UNLOCK(conn->_queueGate); break; /* @@ -1478,9 +1509,9 @@ static int messages_received_count; int sequence; [rmc decodeValueOfObjCType: @encode(int) at: &sequence]; - [conn->_queueGate lock]; + M_LOCK(conn->_queueGate); NSMapInsert(conn->_replyMap, (void*)sequence, rmc); - [conn->_queueGate unlock]; + M_UNLOCK(conn->_queueGate); } break; @@ -1523,7 +1554,6 @@ static int messages_received_count; "-awake..." methods will get sent before the __builtin_apply! */ if (argnum == -1 && datum == 0 && type == 0) { - [aRmc dismiss]; return; } @@ -1532,10 +1562,10 @@ static int messages_received_count; for char*'s. We need to make sure it gets freed eventually so we don't have a memory leak. Request here that it be autorelease'ed. Also autorelease created objects. */ - if (*type == _C_CHARPTR) + if ((*type == _C_CHARPTR || *type == _C_PTR) && *(void**)datum != 0) [NSData dataWithBytesNoCopy: *(void**)datum length: 1]; else if (*type == _C_ID) - [*(id*)datum autorelease]; + AUTORELEASE(*(id*)datum); } void encoder (int argnum, void *datum, const char *type, int flags) @@ -1554,18 +1584,18 @@ static int messages_received_count; } switch (*type) { - case _C_ID: - if (flags & _F_BYCOPY) - [op encodeBycopyObject: *(id*)datum]; + case _C_ID: + if (flags & _F_BYCOPY) + [op encodeBycopyObject: *(id*)datum]; #ifdef _F_BYREF - else if (flags & _F_BYREF) - [op encodeByrefObject: *(id*)datum]; + else if (flags & _F_BYREF) + [op encodeByrefObject: *(id*)datum]; #endif - else - [op encodeObject: *(id*)datum]; - break; - default: - [op encodeValueOfObjCType: type at: datum]; + else + [op encodeObject: *(id*)datum]; + break; + default: + [op encodeValueOfObjCType: type at: datum]; } } @@ -1589,7 +1619,10 @@ static int messages_received_count; NSLog(@"Handling message from 0x%x", (gsaddr)self); _reqInCount++; /* Handling an incoming request. */ mframe_do_call (forward_type, decoder, encoder); - [self _sendRmc: op type: METHOD_REPLY]; + if (op != nil) + { + [self _sendRmc: op type: METHOD_REPLY]; + } } /* Make sure we pass all exceptions back to the requestor. */ @@ -1604,7 +1637,7 @@ static int messages_received_count; { op = [self _makeRmc: reply_sequence_number]; [op encodeValueOfObjCType: @encode(BOOL) - at: &is_exception]; + at: &is_exception]; [op encodeBycopyObject: localException]; [self _sendRmc: op type: METHOD_REPLY]; } @@ -1617,9 +1650,10 @@ static int messages_received_count; } } NS_ENDHANDLER; - - if (forward_type) - objc_free (forward_type); + if (forward_type != 0) + { + NSZoneFree(NSDefaultMallocZone(), forward_type); + } } - (void) _service_rootObject: (NSPortCoder*)rmc @@ -1633,6 +1667,7 @@ static int messages_received_count; NSParameterAssert([rmc connection] == self); [rmc decodeValueOfObjCType: @encode(int) at: &sequence]; + op = [self _makeRmc: sequence]; [op encodeObject: rootObject]; [self _sendRmc: op type: ROOTPROXY_REPLY]; } @@ -1690,7 +1725,7 @@ static int messages_received_count; { GSLocalCounter *counter; - [global_proxies_gate lock]; + M_LOCK(global_proxies_gate); counter = NSMapGet (all_connections_local_targets, (void*)target); if (counter == nil) { @@ -1713,7 +1748,7 @@ static int messages_received_count; NSLog(@"target (0x%x) moved from cache", target); } } - [global_proxies_gate unlock]; + M_UNLOCK(global_proxies_gate); if (counter == nil) { [op encodeObject: @"target not found anywhere"]; @@ -1818,23 +1853,23 @@ static int messages_received_count; NSPortCoder *rmc; NSDate *timeout_date = nil; - [_queueGate lock]; + M_LOCK(_queueGate); while ((rmc = (NSPortCoder*)NSMapGet(_replyMap, (void*)sn)) == nil) { if (timeout_date == nil) { timeout_date = [NSDate dateWithTimeIntervalSinceNow: _replyTimeout]; } - [_queueGate unlock]; + M_UNLOCK(_queueGate); if ([NSRunLoop runOnceBeforeDate: timeout_date forMode: NSConnectionReplyMode] == NO) { [NSException raise: NSPortTimeoutException format: @"timed out waiting for reply"]; } - [_queueGate lock]; + M_LOCK(_queueGate); } - [_queueGate unlock]; + M_UNLOCK(_queueGate); return rmc; } @@ -1844,7 +1879,7 @@ static int messages_received_count; NSParameterAssert(_isValid); - coder = [GSPortCoder portCoderWithReceivePort: [self receivePort] + coder = [NSPortCoder portCoderWithReceivePort: [self receivePort] sendPort: [self sendPort] components: nil]; [coder encodeValueOfObjCType: @encode(int) at: &sequence]; @@ -1856,9 +1891,9 @@ static int messages_received_count; int n; NSParameterAssert (_isValid); - [sequenceNumberGate lock]; + M_LOCK(sequenceNumberGate); n = _messageCount++; - [sequenceNumberGate unlock]; + M_UNLOCK(sequenceNumberGate); return n; } @@ -1945,8 +1980,8 @@ static int messages_received_count; GSLocalCounter *counter; NSParameterAssert (_isValid); - [_proxiesGate lock]; - [global_proxies_gate lock]; + M_LOCK(_proxiesGate); + M_LOCK(global_proxies_gate); /* xxx Do we need to check to make sure it's not already there? */ /* This retains object. */ NSMapInsert(_localObjects, (void*)object, anObj); @@ -1974,8 +2009,8 @@ static int messages_received_count; NSLog(@"add local object (0x%x) target (0x%x) " @"to connection (0x%x) (ref %d)", (gsaddr)object, target, (gsaddr) self, counter->ref); - [global_proxies_gate unlock]; - [_proxiesGate unlock]; + M_UNLOCK(global_proxies_gate); + M_UNLOCK(_proxiesGate); } - (NSDistantObject*) localForObject: (id)object @@ -1983,9 +2018,9 @@ static int messages_received_count; NSDistantObject *p; /* Don't assert (_isValid); */ - [_proxiesGate lock]; + M_LOCK(_proxiesGate); p = NSMapGet (_localObjects, (void*)object); - [_proxiesGate unlock]; + M_UNLOCK(_proxiesGate); NSParameterAssert(!p || [p connectionForProxy] == self); return p; } @@ -2010,8 +2045,8 @@ static int messages_received_count; GSLocalCounter *counter; unsigned val = 0; - [global_proxies_gate lock]; - [_proxiesGate lock]; + M_LOCK(global_proxies_gate); + M_LOCK(_proxiesGate); prox = NSMapGet(_localObjects, (void*)anObj); target = [prox targetForProxy]; @@ -2061,8 +2096,8 @@ static int messages_received_count; @"from connection (0x%x) (ref %d)", (gsaddr)anObj, target, (gsaddr)self, val); - [_proxiesGate unlock]; - [global_proxies_gate unlock]; + M_UNLOCK(_proxiesGate); + M_UNLOCK(global_proxies_gate); } - (void) _release_targets: (unsigned*)list count: (unsigned)number @@ -2126,7 +2161,6 @@ static int messages_received_count; [ip decodeValueOfObjCType: @encode(id) at: &result]; if (result != nil) NSLog(@"failed to retain target - %@", result); - [ip dismiss]; } } NS_HANDLER @@ -2141,10 +2175,10 @@ static int messages_received_count; unsigned target = [aProxy targetForProxy]; /* Don't assert (_isValid); */ - [_proxiesGate lock]; + M_LOCK(_proxiesGate); /* This also releases aProxy */ NSMapRemove(_remoteProxies, (void*)target); - [_proxiesGate unlock]; + M_UNLOCK(_proxiesGate); /* * Tell the remote application that we have removed our proxy and @@ -2158,9 +2192,9 @@ static int messages_received_count; NSDistantObject *p; /* Don't assert (_isValid); */ - [_proxiesGate lock]; + M_LOCK(_proxiesGate); p = NSMapGet(_remoteProxies, (void*)target); - [_proxiesGate unlock]; + M_UNLOCK(_proxiesGate); NSParameterAssert(!p || [p connectionForProxy] == self); return p; } @@ -2172,15 +2206,15 @@ static int messages_received_count; NSParameterAssert (_isValid); NSParameterAssert(aProxy->isa == [NSDistantObject class]); NSParameterAssert([aProxy connectionForProxy] == self); - [_proxiesGate lock]; + M_LOCK(_proxiesGate); if (NSMapGet(_remoteProxies, (void*)target)) { - [_proxiesGate unlock]; + M_UNLOCK(_proxiesGate); [NSException raise: NSGenericException format: @"Trying to add the same proxy twice"]; } NSMapInsert(_remoteProxies, (void*)target, aProxy); - [_proxiesGate unlock]; + M_UNLOCK(_proxiesGate); } - (id) includesProxyForTarget: (unsigned)target @@ -2188,9 +2222,9 @@ static int messages_received_count; NSDistantObject *ret; /* Don't assert (_isValid); */ - [_proxiesGate lock]; + M_LOCK(_proxiesGate); ret = NSMapGet (_remoteProxies, (void*)target); - [_proxiesGate unlock]; + M_UNLOCK(_proxiesGate); return ret; } @@ -2199,9 +2233,9 @@ static int messages_received_count; NSDistantObject *ret; /* Don't assert (_isValid); */ - [_proxiesGate lock]; + M_LOCK(_proxiesGate); ret = NSMapGet(_localObjects, (void*)anObj); - [_proxiesGate unlock]; + M_UNLOCK(_proxiesGate); return ret; } @@ -2210,9 +2244,9 @@ static int messages_received_count; NSDistantObject *ret; /* Don't assert (_isValid); */ - [_proxiesGate lock]; + M_LOCK(_proxiesGate); ret = NSMapGet(_localTargets, (void*)target); - [_proxiesGate unlock]; + M_UNLOCK(_proxiesGate); return ret; } @@ -2227,9 +2261,9 @@ static int messages_received_count; id ret; /* Don't assert (_isValid); */ - [global_proxies_gate lock]; + M_LOCK(global_proxies_gate); ret = NSMapGet(all_connections_local_targets, (void*)target); - [global_proxies_gate unlock]; + M_UNLOCK(global_proxies_gate); return ret; } diff --git a/Source/GSPortCoder.m b/Source/GSPortCoder.m index b7a083727..ea47a8b1b 100644 --- a/Source/GSPortCoder.m +++ b/Source/GSPortCoder.m @@ -43,7 +43,6 @@ #include #include -#include #include /* @@ -73,6 +72,8 @@ #include #undef _IN_PORT_CODER_M +#include + static BOOL debug_port_coder = NO; typedef unsigned char uchar; @@ -266,7 +267,7 @@ typeCheck(char t1, char t2) -@interface GSPortCoder (Private) +@interface NSPortCoder (Private) - (void) _deserializeHeaderAt: (unsigned*)pos version: (unsigned*)v classes: (unsigned*)c @@ -282,7 +283,7 @@ typeCheck(char t1, char t2) @end -@implementation GSPortCoder +@implementation NSPortCoder + (NSPortCoder*) portCoderWithReceivePort: (NSPort*)recv sendPort: (NSPort*)send @@ -1216,7 +1217,7 @@ typeCheck(char t1, char t2) } obj = [anObject replacementObjectForPortCoder: self]; - cls = [anObject classForPortCoder]; + cls = [obj classForPortCoder]; (*_xRefImp)(_dst, xRefSel, _GSC_ID, node->value.uint); (*_eValImp)(self, eValSel, @encode(Class), &cls); @@ -1294,6 +1295,11 @@ typeCheck(char t1, char t2) type++; } + if (_initialPass == NO) + { + (*_eTagImp)(_dst, eTagSel, _GSC_ARY_B); + } + [self encodeArrayOfObjCType: type count: count at: buf]; } return; @@ -1668,7 +1674,7 @@ typeCheck(char t1, char t2) -@implementation GSPortCoder (Private) +@implementation NSPortCoder (Private) - (NSMutableArray*) _components { @@ -1752,7 +1758,7 @@ typeCheck(char t1, char t2) /* * Read header including version and crossref table sizes. */ - _cursor = [[_conn sendPort] reservedSpaceLength]; + _cursor = 0; [self _deserializeHeaderAt: &_cursor version: &_version classes: &sizeC diff --git a/Source/GSTcpPort.m b/Source/GSTcpPort.m index 34cc20e10..61369fbf8 100644 --- a/Source/GSTcpPort.m +++ b/Source/GSTcpPort.m @@ -1521,15 +1521,20 @@ static NSMapTable *tcpPortMap = 0; } - (BOOL) sendBeforeDate: (NSDate*)when + msgid: (int)msgId components: (NSMutableArray*)components from: (NSPort*)receivingPort reserved: (unsigned)length - msgId: (int)msgId { BOOL sent = NO; GSTcpHandle *h; unsigned rl = [self reservedSpaceLength]; + if ([components count] == 0) + { + NSLog(@"empty components sent"); + return NO; + } /* * If the reserved length in the first data object is wrong - we have to * fail, unless it's zero, in which case we can insert a data object for @@ -1669,18 +1674,6 @@ static NSMapTable *tcpPortMap = 0; return sent; } -- (BOOL) sendBeforeDate: (NSDate*)when - components: (NSMutableArray*)components - from: (NSPort*)receivingPort - reserved: (unsigned)length -{ - return [self sendBeforeDate: (NSDate*)when - components: components - from: receivingPort - reserved: length - msgId: GS_CONNECTION_MSG]; -} - - (NSDate*) timedOutEvent: (void*)data type: (RunLoopEventType)type forMode: (NSString*)mode diff --git a/Source/NSArchiver.m b/Source/NSArchiver.m index c6d653781..4115912d1 100644 --- a/Source/NSArchiver.m +++ b/Source/NSArchiver.m @@ -261,6 +261,11 @@ static SEL eValSel = @selector(encodeValueOfObjCType:at:); type++; } + if (_initialPass == NO) + { + (*_tagImp)(_dst, tagSel, _GSC_ARY_B); + } + [self encodeArrayOfObjCType: type count: count at: buf]; } return; @@ -762,7 +767,7 @@ static SEL eValSel = @selector(encodeValueOfObjCType:at:); } obj = [anObject replacementObjectForArchiver: self]; - cls = [anObject classForArchiver]; + cls = [obj classForArchiver]; (*_xRefImp)(_dst, xRefSel, _GSC_ID, node->value.uint); if (_namMap->nodeCount) diff --git a/Source/NSData.m b/Source/NSData.m index f45bf39a7..4e7d43d1e 100644 --- a/Source/NSData.m +++ b/Source/NSData.m @@ -826,15 +826,12 @@ failure: else { unsigned len = (length+1)*sizeof(char); - NSZone *z = [self zone]; - NSData *d; - *(char**)data = (char*)NSZoneMalloc(z, len); - d = [dataMalloc allocWithZone: z]; - d = [d initWithBytesNoCopy: *(void**)data - length: len - fromZone: z]; - IF_NO_GC(AUTORELEASE(d)); +#if GS_WITH_GC == 0 + *(char**)data = (char*)NSZoneMalloc(NSDefaultMallocZone(), len); +#else + *(char**)data = (char*)NSZoneMalloc(NSAtomicMallocZone(), len); +#endif } [self deserializeBytes: *(char**)data @@ -896,15 +893,12 @@ failure: case _C_PTR: { unsigned len = objc_sizeof_type(++type); - NSZone *z = [self zone]; - NSData *d; - *(char**)data = (char*)NSZoneMalloc(z, len); - d = [dataMalloc allocWithZone: z]; - d = [d initWithBytesNoCopy: *(void**)data - length: len - fromZone: z]; - IF_NO_GC(AUTORELEASE(d)); +#if GS_WITH_GC == 0 + *(char**)data = (char*)NSZoneMalloc(NSDefaultMallocZone(), len); +#else + *(char**)data = (char*)NSZoneMalloc(NSAtomicMallocZone(), len); +#endif [self deserializeDataAt: *(char**)data ofObjCType: type atCursor: cursor @@ -1937,14 +1931,10 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos) } else { - NSZone *z = [self zone]; - - *(char**)data = (char*)NSZoneMalloc(z, len+1); -#if !GS_WITH_GC - [[[dataMalloc allocWithZone: z] - initWithBytesNoCopy: *(void**)data - length: len+1 - fromZone: z] autorelease]; +#if GS_WITH_GC == 0 + *(char**)data = (char*)NSZoneMalloc(NSDefaultMallocZone(), len+1); +#else + *(char**)data = (char*)NSZoneMalloc(NSAtomicMallocZone(), len+1); #endif } getBytes(*(void**)data, bytes, len, length, cursor); @@ -2004,14 +1994,11 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos) case _C_PTR: { unsigned len = objc_sizeof_type(++type); - NSZone *z = [self zone]; - *(char**)data = (char*)NSZoneMalloc(z, len); -#if !GS_WITH_GC - [[[dataMalloc allocWithZone: z] - initWithBytesNoCopy: *(void**)data - length: len - fromZone: z] autorelease]; +#if GS_WITH_GC == 0 + *(char**)data = (char*)NSZoneMalloc(NSDefaultMallocZone(), len); +#else + *(char**)data = (char*)NSZoneMalloc(NSAtomicMallocZone(), len); #endif [self deserializeDataAt: *(char**)data ofObjCType: type diff --git a/Source/NSDistantObject.m b/Source/NSDistantObject.m index 683678e15..4c7b2da52 100644 --- a/Source/NSDistantObject.m +++ b/Source/NSDistantObject.m @@ -44,6 +44,7 @@ static Class distantObjectClass = 0; * allocating the memory for a new instance unless absolutely necessary. */ @interface GSDistantObjectPlaceHolder ++ (id) initWithCoder: (NSCoder*)aCoder; + (id) initWithLocal: (id)anObject connection: (NSConnection*)aConnection; + (id) initWithTarget: (unsigned)target connection: (NSConnection*)aConnection; + (void) autorelease; @@ -74,6 +75,15 @@ static Class distantObjectClass = 0; } } ++ (id) initWithCoder: (NSCoder*)aCoder +{ + NSDistantObject *proxy; + + proxy = (NSDistantObject*)NSAllocateObject(distantObjectClass, + 0, NSDefaultMallocZone()); + return [proxy initWithCoder: aCoder]; +} + + (id) initWithLocal: (id)anObject connection: (NSConnection*)aConnection { NSDistantObject *proxy; @@ -182,10 +192,14 @@ enum gsu8 proxy_tag; NSConnection *encoder_connection; - if ([aRmc class] != [PortEncoder class]) - [NSException raise: NSGenericException - format: @"NSDistantObject objects only " - @"encode with PortEncoder class"]; +/* + if ([aRmc isKindOfClass: [NSPortCoder class]] == NO) + { + [NSException raise: NSGenericException + format: @"NSDistantObject objects only " + @"encode with NSPortCoder class"]; + } +*/ encoder_connection = [(NSPortCoder*)aRmc connection]; NSAssert(encoder_connection, NSInternalInconsistencyException); @@ -299,13 +313,15 @@ enum unsigned target; id decoder_connection; - if ([aCoder class] != [PortDecoder class]) +/* + if ([aCoder isKindOfClass: [NSPortCoder class]] == NO) { [self release]; [NSException raise: NSGenericException format: @"NSDistantObject objects only decode with " - @"PortDecoder class"]; + @"NSPortCoder class"]; } +*/ decoder_connection = [(NSPortCoder*)aCoder connection]; NSAssert(decoder_connection, NSInternalInconsistencyException); @@ -734,7 +750,7 @@ static inline BOOL class_is_kind_of (Class self, Class aClassObject) return [self class]; } -- replacementObjectForPortCoder: (NSPortCoder*)aRmc; +- (id) replacementObjectForPortCoder: (NSPortCoder*)aRmc; { if ([aRmc isBycopy]) return self; diff --git a/Source/NSInvocation.m b/Source/NSInvocation.m index 3ad0cae11..c48e2dec0 100644 --- a/Source/NSInvocation.m +++ b/Source/NSInvocation.m @@ -440,6 +440,7 @@ [aCoder decodeValueOfObjCType: @encode(char*) at: &types]; newSig = [NSMethodSignature signatureWithObjCTypes: types]; + NSZoneFree(NSDefaultMallocZone(), (void*)types); self = [self initWithMethodSignature: newSig]; [aCoder decodeValueOfObjCType: @encode(id) at: &_target]; diff --git a/Source/NSPort.m b/Source/NSPort.m index d282e3c90..1d43fc721 100644 --- a/Source/NSPort.m +++ b/Source/NSPort.m @@ -31,11 +31,28 @@ #include #include +@class GSTcpPort; + @implementation NSPort +Class _concreteClass; + ++ (id) allocWithZone: (NSZone*)aZone +{ + return [super allocWithZone: aZone]; +} + ++ (void) initialize +{ + if (self == [NSPort class]) + { + _concreteClass = [GSTcpPort class]; + } +} + + (NSPort*) port { - return AUTORELEASE([self new]); + return AUTORELEASE([_concreteClass new]); } + (NSPort*) portWithMachPort: (int)machPort @@ -159,6 +176,19 @@ components: (NSMutableArray*)components from: (NSPort*)receivingPort reserved: (unsigned) length +{ + return [self sendBeforeDate: when + msgid: 0 + components: components + from: receivingPort + reserved: length]; +} + +- (BOOL) sendBeforeDate: (NSDate*)when + msgid: (int)msgid + components: (NSMutableArray*)components + from: (NSPort*)receivingPort + reserved: (unsigned)length { [self subclassResponsibility: _cmd]; return YES; diff --git a/Source/NSPortNameServer.m b/Source/NSPortNameServer.m index acb460fba..f40333a12 100644 --- a/Source/NSPortNameServer.m +++ b/Source/NSPortNameServer.m @@ -518,6 +518,7 @@ typedef enum { launchCmd = [NSString stringWithCString: make_gdomap_cmd(GNUSTEP_INSTALL_PREFIX)]; portClass = [TcpOutPort class]; +// portClass = [GSTcpPort class]; } } diff --git a/Testing/client.m b/Testing/client.m index 7a8694a28..e8b9ccc4f 100644 --- a/Testing/client.m +++ b/Testing/client.m @@ -8,12 +8,9 @@ #include #include #include -#include #include #include "server.h" -@class TcpInPort; -@class PortDecoder; int main (int argc, char *argv[]) { @@ -43,9 +40,7 @@ int main (int argc, char *argv[]) GSDebugAllocationActive(YES); [NSConnection setDebug: 10]; [NSDistantObject setDebug: 10]; - [TcpInPort setDebug: 10]; - - [BinaryCStream setDebugging:YES]; + [NSPort setDebug: 10]; #if NeXT_runtime [NSDistantObject setProtocolForProxies:@protocol(AllProxies)]; @@ -54,29 +49,25 @@ printf("oneway %d\n", _F_ONEWAY); if (argc > 1) { if (argc > 2) - p = [NSConnection rootProxyAtName: [NSString stringWithCString: argv[2]] - onHost: [NSString stringWithCString:argv[1]]]; + p = [NSConnection rootProxyForConnectionWithRegisteredName: [NSString stringWithCString: argv[2]] + host: [NSString stringWithCString:argv[1]]]; else - p = [NSConnection rootProxyAtName:@"test2server" - onHost:[NSString stringWithCString:argv[1]]]; + p = [NSConnection rootProxyForConnectionWithRegisteredName:@"test2server" + host:[NSString stringWithCString:argv[1]]]; } else - p = [NSConnection rootProxyAtName:@"test2server" - onHost:nil]; + p = [NSConnection rootProxyForConnectionWithRegisteredName:@"test2server" + host:nil]; c = [p connectionForProxy]; [c setRequestTimeout:180.0]; [c setReplyTimeout:180.0]; localObj = [[NSObject alloc] init]; [p outputStats:localObj]; -fprintf(stderr, "XXXXXXXXXXXXXXXXA %d\n", GSDebugAllocationCount([PortDecoder class])); [p getLong:&i]; -fprintf(stderr,"XXXXXXXXXXXXXXXXB %d\n", GSDebugAllocationCount([PortDecoder class])); [p getLong:&i]; [p outputStats:localObj]; -fprintf(stderr,"XXXXXXXXXXXXXXXXC %d\n", GSDebugAllocationCount([PortDecoder class])); type = [c typeForSelector:sel_get_any_uid("name") remoteTarget:[p targetForProxy]]; -printf("XXXXXXXXXXXXXXXXD %d\n", GSDebugAllocationCount([PortDecoder class])); printf(">>type = %s\n", type); printf(">>list proxy's hash is 0x%x\n", (unsigned)[p hash]); diff --git a/Testing/server.m b/Testing/server.m index 22f956cdd..9b2cc3a3f 100644 --- a/Testing/server.m +++ b/Testing/server.m @@ -251,12 +251,15 @@ int main(int argc, char *argv[]) #if NeXT_runtime [NSDistantObject setProtocolForProxies:@protocol(AllProxies)]; #endif + + c = [NSConnection defaultConnection]; + [c setRootObject: l]; + if (argc > 1) - c = [NSConnection newRegisteringAtName: - [NSString stringWithCString: argv[1]] - withRootObject:l]; + [c registerName: [NSString stringWithCString: argv[1]]]; else - c = [NSConnection newRegisteringAtName:@"test2server" withRootObject:l]; + [c registerName: @"test2server"]; + [[NSNotificationCenter defaultCenter] addObserver: l selector: @selector(connectionBecameInvalid:)