diff --git a/ChangeLog b/ChangeLog index baf048bbc..872cf05d4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2000-07-05 Richard Frith-Macdonald + + * Source/GSTcpHandle.m: fix error resetting size of data to be read - + could cause occasional crashes! + 2000-07-05 Richard Frith-Macdonald * Source/NSConnection.m: Update to use GSIMap rather than NSMap in diff --git a/Headers/gnustep/base/DistributedObjects.h b/Headers/gnustep/base/DistributedObjects.h index e8cdf2757..e8dc1439f 100644 --- a/Headers/gnustep/base/DistributedObjects.h +++ b/Headers/gnustep/base/DistributedObjects.h @@ -39,13 +39,9 @@ #include #include -@class InPacket; - @class NSDistantObject; @class NSConnection; @class NSPort; -@class PortDecoder; -@class PortEncoder; /* * Distributed Objects identifiers @@ -74,36 +70,8 @@ enum { + (NSDistantObject*) includesLocalTarget: (unsigned)target; - (NSDistantObject*) includesLocalTarget: (unsigned)target; - (NSDistantObject*) localForObject: (id)object; -- (NSDistantObject*) localForTarget: (unsigned)target; - (NSDistantObject*) proxyForTarget: (unsigned)target; -+ (void) removeLocalObject: (id)object; -- (void) removeLocalObject: (id)object; - (void) retainTarget: (unsigned)target; @end - -/* - * Catagory containing the methods by which the public interface to - * NSPortCoder must be extended in order to allow it's use by - * by NSConnection et al for implementation of Distributed objects. - */ -@interface NSPortCoder (Internal) - -+ newDecodingWithPacket: (InPacket*)packet - connection: (NSConnection*)c; - -+ newDecodingWithConnection: (NSConnection*)c - timeout: (int) timeout; - -+ newForWritingWithConnection: (NSConnection*)c - sequenceNumber: (int)n - identifier: (int)i; - -- (void) dismiss; -- (unsigned) sequenceNumber; -- (int) identifier; -- (NSPort*) replyPort; - -@end - #endif /* __DistributedObjects_h */ diff --git a/Source/GSTcpPort.m b/Source/GSTcpPort.m index 6cdfafd24..2224bbfc8 100644 --- a/Source/GSTcpPort.m +++ b/Source/GSTcpPort.m @@ -768,6 +768,7 @@ static Class runLoopClass; { memcpy(bytes, bytes + rWant, rLength); } + rWant = sizeof(GSPortItemHeader); if (nItems == [rItems count]) { [self dispatch]; @@ -1649,7 +1650,6 @@ static Class tcpPortClass; * a maximum of NETBLOCK bytes. This is to try to get a single, * efficient write operation if possible. */ - c = [components count]; for (i = 1; i < c; i++) { id o = [components objectAtIndex: i]; diff --git a/Source/NSConnection.m b/Source/NSConnection.m index 6c6736485..5ec7a7ef2 100644 --- a/Source/NSConnection.m +++ b/Source/NSConnection.m @@ -72,10 +72,21 @@ #define M_LOCK(X) {NSDebugMLLog(@"GSConnection",@"Lock %@",X);[X lock];} #define M_UNLOCK(X) {NSDebugMLLog(@"GSConnection",@"Unlock %@",X);[X unlock];} +/* + * Set up a type to permit us to have direct access into an NSDistantObject + */ +typedef struct { + @defs(NSDistantObject) +} ProxyStruct; + +/* + * Cache various class pointers. + */ static id dummyObject; static Class connectionClass; static Class dateClass; static Class distantObjectClass; +static Class localCounterClass; static Class portCoderClass; static Class runLoopClass; @@ -109,27 +120,6 @@ stringFromMsgType(int type) } } -@interface NSDistantObject (NSConnection) -- (id) localForProxy; -- (void) setProxyTarget: (unsigned)target; -- (unsigned) targetForProxy; -@end - -@implementation NSDistantObject (NSConnection) -- (id) localForProxy -{ - return _object; -} -- (void) setProxyTarget: (unsigned)target -{ - _handle = target; -} -- (unsigned) targetForProxy -{ - return _handle; -} -@end - /* * GSLocalCounter is a trivial class to keep track of how * many different connections a particular local object is vended @@ -226,6 +216,10 @@ static unsigned local_object_counter = 0; - (void) _runInNewThread; + (void) setDebug: (int)val; +- (void) addLocalObject: (NSDistantObject*)anObj; +- (NSDistantObject*) localForObject: (id)object; +- (void) removeLocalObject: (id)anObj; + - (void) _doneInRmc: (NSPortCoder*)c; - (NSPortCoder*) _getReplyRmc: (int)sn; - (NSPortCoder*) _makeInRmc: (NSMutableArray*)components; @@ -245,7 +239,7 @@ static unsigned local_object_counter = 0; /* class defaults */ -static NSTimer *timer; +static NSTimer *timer; static int debug_connection = 0; @@ -318,9 +312,9 @@ setRootObjectForInPort(id anObj, NSPort *aPort) F_UNLOCK(root_object_map_gate); } -static NSMapTable *all_connections_local_objects = NULL; -static NSMapTable *all_connections_local_targets = NULL; -static NSMapTable *all_connections_local_cached = NULL; +static NSMapTable *objectToCounter = NULL; +static NSMapTable *targetToCounter = NULL; +static NSMapTable *targetToCached = NULL; static NSLock *global_proxies_gate; @@ -438,6 +432,7 @@ static NSLock *global_proxies_gate; connectionClass = self; dateClass = [NSDate class]; distantObjectClass = [NSDistantObject class]; + localCounterClass = [GSLocalCounter class]; portCoderClass = [NSPortCoder class]; runLoopClass = [NSRunLoop class]; @@ -446,14 +441,14 @@ static NSLock *global_proxies_gate; connection_table = NSCreateHashTable(NSNonRetainedObjectHashCallBacks, 0); connection_table_gate = [NSLock new]; - /* xxx When NSHashTable's are working, change this. */ - all_connections_local_objects = + + objectToCounter = NSCreateMapTable(NSNonOwnedPointerMapKeyCallBacks, NSObjectMapValueCallBacks, 0); - all_connections_local_targets = + targetToCounter = NSCreateMapTable(NSIntMapKeyCallBacks, NSNonOwnedPointerMapValueCallBacks, 0); - all_connections_local_cached = + targetToCached = NSCreateMapTable(NSIntMapKeyCallBacks, NSObjectMapValueCallBacks, 0); global_proxies_gate = [NSLock new]; @@ -510,7 +505,7 @@ static NSLock *global_proxies_gate; NSArray *cached_locals; int i; - cached_locals = NSAllMapTableValues(all_connections_local_cached); + cached_locals = NSAllMapTableValues(targetToCached); for (i = [cached_locals count]; i > 0; i--) { CachedLocalObject *item = [cached_locals objectAtIndex: i-1]; @@ -518,7 +513,7 @@ static NSLock *global_proxies_gate; if ([item countdown] == NO) { GSLocalCounter *counter = [item obj]; - NSMapRemove(all_connections_local_cached, (void*)counter->target); + NSMapRemove(targetToCached, (void*)counter->target); } } if ([cached_locals count] == 0) @@ -710,7 +705,8 @@ static NSLock *global_proxies_gate; GSIMapInitWithZoneAndCapacity(_localTargets, z, 4); /* - * This maps [proxy targetForProxy] to proxy. The proxy's are retained. + * This maps targets to remote proxies. + * The proxy's must be retained on addition and released on removal. */ _remoteProxies = (GSIMapTable)NSZoneMalloc(z, sizeof(GSIMapTable_t)); GSIMapInitWithZoneAndCapacity(_remoteProxies, z, 4); @@ -893,7 +889,7 @@ static NSLock *global_proxies_gate; } while (i-- > 0) { - id t = [[targets objectAtIndex: i] localForProxy]; + id t = ((ProxyStruct*)[targets objectAtIndex: i])->_object; [self removeLocalObject: t]; } @@ -1846,7 +1842,7 @@ static NSLock *global_proxies_gate; if (debug_connection > 3) NSLog(@"releasing object with target (0x%x) on (0x%x)", target, (gsaddr)self); - [self removeLocalObject: [prox localForProxy]]; + [self removeLocalObject: ((ProxyStruct*)prox)->_object]; } else if (debug_connection > 3) NSLog(@"releasing object with target (0x%x) on (0x%x) - nothing to do", @@ -1878,7 +1874,7 @@ static NSLock *global_proxies_gate; GSLocalCounter *counter; M_LOCK(global_proxies_gate); - counter = NSMapGet (all_connections_local_targets, (void*)target); + counter = NSMapGet (targetToCounter, (void*)target); if (counter == nil) { /* @@ -1887,15 +1883,15 @@ static NSLock *global_proxies_gate; * we move it back from the cache to the main maps so we can * retain it on this connection. */ - counter = NSMapGet (all_connections_local_cached, (void*)target); + counter = NSMapGet (targetToCached, (void*)target); if (counter) { unsigned t = counter->target; id o = counter->object; - NSMapInsert(all_connections_local_objects, (void*)o, counter); - NSMapInsert(all_connections_local_targets, (void*)t, counter); - NSMapRemove(all_connections_local_cached, (void*)t); + NSMapInsert(objectToCounter, (void*)o, counter); + NSMapInsert(targetToCounter, (void*)t, counter); + NSMapRemove(targetToCached, (void*)t); if (debug_connection > 3) NSLog(@"target (0x%x) moved from cache", target); } @@ -1969,7 +1965,7 @@ static NSLock *global_proxies_gate; [rmc decodeValueOfObjCType: @encode(unsigned) at: &target]; [self _doneInRmc: rmc]; p = [self includesLocalTarget: target]; - o = [p localForProxy]; + o = ((ProxyStruct*)p)->_object; /* xxx We should make sure that TARGET is a valid object. */ /* Not actually a Proxy, but we avoid the warnings "id" would have made. */ @@ -2241,40 +2237,39 @@ static NSLock *global_proxies_gate; } - /* Managing objects and proxies. */ -- (void) addLocalObject: (id)anObj +- (void) addLocalObject: (NSDistantObject*)anObj { - id object = [anObj localForProxy]; + id object; unsigned target; GSLocalCounter *counter; GSIMapNode node; - - NSParameterAssert (_isValid); M_LOCK(_proxiesGate); M_LOCK(global_proxies_gate); + NSParameterAssert (_isValid); /* * Record the value in the _localObjects map, retaining it. */ + object = ((ProxyStruct*)anObj)->_object; node = GSIMapNodeForKey(_localObjects, (GSIMapKey)object); IF_NO_GC(RETAIN(anObj)); - if (node) + if (node == 0) { - RELEASE(node->value.obj); - node->value.obj = anObj; + GSIMapAddPair(_localObjects, (GSIMapKey)object, (GSIMapVal)anObj); } else { - GSIMapAddPair(_localObjects, (GSIMapKey)object, (GSIMapVal)anObj); + RELEASE(node->value.obj); + node->value.obj = anObj; } /* * Keep track of local objects accross all connections. */ - counter = NSMapGet(all_connections_local_objects, (void*)object); + counter = NSMapGet(objectToCounter, (void*)object); if (counter) { counter->ref++; @@ -2282,13 +2277,13 @@ static NSLock *global_proxies_gate; } else { - counter = [GSLocalCounter newWithObject: object]; + counter = [localCounterClass newWithObject: object]; target = counter->target; - NSMapInsert(all_connections_local_objects, (void*)object, counter); - NSMapInsert(all_connections_local_targets, (void*)target, counter); + NSMapInsert(objectToCounter, (void*)object, counter); + NSMapInsert(targetToCounter, (void*)target, counter); RELEASE(counter); } - [anObj setProxyTarget: target]; + ((ProxyStruct*)anObj)->_handle = target; GSIMapAddPair(_localTargets, (GSIMapKey)target, (GSIMapVal)anObj); if (debug_connection > 2) NSLog(@"add local object (0x%x) target (0x%x) " @@ -2319,19 +2314,6 @@ static NSLock *global_proxies_gate; return p; } -/* This should get called whenever an object free's itself */ -+ (void) removeLocalObject: (id)anObj -{ - NSHashEnumerator enumerator; - NSConnection *o; - - enumerator = NSEnumerateHashTable(connection_table); - while ((o = (NSConnection*)NSNextHashEnumeratorItem(&enumerator)) != nil) - { - [o removeLocalObject: anObj]; - } -} - - (void) removeLocalObject: (id)anObj { NSDistantObject *prox; @@ -2352,13 +2334,13 @@ static NSLock *global_proxies_gate; { prox = node->value.obj; } - target = [prox targetForProxy]; + target = ((ProxyStruct*)prox)->_handle; /* * If all references to a local proxy have gone - remove the * global reference as well. */ - counter = NSMapGet(all_connections_local_objects, (void*)anObj); + counter = NSMapGet(objectToCounter, (void*)anObj); if (counter) { counter->ref--; @@ -2381,14 +2363,14 @@ static NSLock *global_proxies_gate; repeats: YES]; } item = [CachedLocalObject newWithObject: counter time: 30]; - NSMapInsert(all_connections_local_cached, (void*)target, item); + NSMapInsert(targetToCached, (void*)target, item); RELEASE(item); if (debug_connection > 3) NSLog(@"placed local object (0x%x) target (0x%x) in cache", (gsaddr)anObj, target); } - NSMapRemove(all_connections_local_objects, (void*)anObj); - NSMapRemove(all_connections_local_targets, (void*)target); + NSMapRemove(objectToCounter, (void*)anObj); + NSMapRemove(targetToCounter, (void*)target); } } @@ -2485,10 +2467,11 @@ static NSLock *global_proxies_gate; - (void) removeProxy: (NSDistantObject*)aProxy { - unsigned target = [aProxy targetForProxy]; + unsigned target; /* Don't assert (_isValid); */ M_LOCK(_proxiesGate); + target = ((ProxyStruct*)aProxy)->_handle; /* This also releases aProxy */ GSIMapRemoveKey(_remoteProxies, (GSIMapKey)target); M_UNLOCK(_proxiesGate); @@ -2522,13 +2505,14 @@ static NSLock *global_proxies_gate; - (void) addProxy: (NSDistantObject*) aProxy { - unsigned target = (unsigned int)[aProxy targetForProxy]; + unsigned target; GSIMapNode node; - NSParameterAssert (_isValid); + M_LOCK(_proxiesGate); + NSParameterAssert(_isValid); NSParameterAssert(aProxy->isa == distantObjectClass); NSParameterAssert([aProxy connectionForProxy] == self); - M_LOCK(_proxiesGate); + target = ((ProxyStruct*)aProxy)->_handle; node = GSIMapNodeForKey(_remoteProxies, (GSIMapKey)target); if (node != 0) { @@ -2612,7 +2596,7 @@ static NSLock *global_proxies_gate; /* Don't assert (_isValid); */ M_LOCK(global_proxies_gate); - ret = NSMapGet(all_connections_local_targets, (void*)target); + ret = NSMapGet(targetToCounter, (void*)target); M_UNLOCK(global_proxies_gate); return ret; } @@ -4504,7 +4488,7 @@ static int messages_received_count; { timer = [NSTimer scheduledTimerWithTimeInterval: 1.0 target: [NSConnection class] - selector: @selector(_timeout: ) + selector: @selector(_timeout:) userInfo: nil repeats: YES]; } diff --git a/Tools/gdomap.c b/Tools/gdomap.c index 81575b561..6854d1117 100644 --- a/Tools/gdomap.c +++ b/Tools/gdomap.c @@ -2148,6 +2148,11 @@ handle_request(int desc) mcopy(&raddr, rbuf, IASIZE); mcopy(&laddr, rbuf+IASIZE, IASIZE); + if (debug > 2) + { + fprintf(stderr, "Probe sent remote '%s'\n", inet_ntoa(raddr)); + fprintf(stderr, "Probe sent local '%s'\n", inet_ntoa(laddr)); + } mcopy(wbuf+IASIZE, &raddr, IASIZE); /*