git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@6876 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
richard 2000-07-05 16:56:06 +00:00
parent b5cd1a215b
commit ff794629ea
5 changed files with 73 additions and 111 deletions

View file

@ -1,3 +1,8 @@
2000-07-05 Richard Frith-Macdonald <rfm@gnu.org>
* Source/GSTcpHandle.m: fix error resetting size of data to be read -
could cause occasional crashes!
2000-07-05 Richard Frith-Macdonald <rfm@gnu.org> 2000-07-05 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSConnection.m: Update to use GSIMap rather than NSMap in * Source/NSConnection.m: Update to use GSIMap rather than NSMap in

View file

@ -39,13 +39,9 @@
#include <Foundation/NSDistantObject.h> #include <Foundation/NSDistantObject.h>
#include <Foundation/NSPortCoder.h> #include <Foundation/NSPortCoder.h>
@class InPacket;
@class NSDistantObject; @class NSDistantObject;
@class NSConnection; @class NSConnection;
@class NSPort; @class NSPort;
@class PortDecoder;
@class PortEncoder;
/* /*
* Distributed Objects identifiers * Distributed Objects identifiers
@ -74,36 +70,8 @@ enum {
+ (NSDistantObject*) includesLocalTarget: (unsigned)target; + (NSDistantObject*) includesLocalTarget: (unsigned)target;
- (NSDistantObject*) includesLocalTarget: (unsigned)target; - (NSDistantObject*) includesLocalTarget: (unsigned)target;
- (NSDistantObject*) localForObject: (id)object; - (NSDistantObject*) localForObject: (id)object;
- (NSDistantObject*) localForTarget: (unsigned)target;
- (NSDistantObject*) proxyForTarget: (unsigned)target; - (NSDistantObject*) proxyForTarget: (unsigned)target;
+ (void) removeLocalObject: (id)object;
- (void) removeLocalObject: (id)object;
- (void) retainTarget: (unsigned)target; - (void) retainTarget: (unsigned)target;
@end @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 */ #endif /* __DistributedObjects_h */

View file

@ -768,6 +768,7 @@ static Class runLoopClass;
{ {
memcpy(bytes, bytes + rWant, rLength); memcpy(bytes, bytes + rWant, rLength);
} }
rWant = sizeof(GSPortItemHeader);
if (nItems == [rItems count]) if (nItems == [rItems count])
{ {
[self dispatch]; [self dispatch];
@ -1649,7 +1650,6 @@ static Class tcpPortClass;
* a maximum of NETBLOCK bytes. This is to try to get a single, * a maximum of NETBLOCK bytes. This is to try to get a single,
* efficient write operation if possible. * efficient write operation if possible.
*/ */
c = [components count];
for (i = 1; i < c; i++) for (i = 1; i < c; i++)
{ {
id o = [components objectAtIndex: i]; id o = [components objectAtIndex: i];

View file

@ -72,10 +72,21 @@
#define M_LOCK(X) {NSDebugMLLog(@"GSConnection",@"Lock %@",X);[X lock];} #define M_LOCK(X) {NSDebugMLLog(@"GSConnection",@"Lock %@",X);[X lock];}
#define M_UNLOCK(X) {NSDebugMLLog(@"GSConnection",@"Unlock %@",X);[X unlock];} #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 id dummyObject;
static Class connectionClass; static Class connectionClass;
static Class dateClass; static Class dateClass;
static Class distantObjectClass; static Class distantObjectClass;
static Class localCounterClass;
static Class portCoderClass; static Class portCoderClass;
static Class runLoopClass; 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 * GSLocalCounter 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
@ -226,6 +216,10 @@ static unsigned local_object_counter = 0;
- (void) _runInNewThread; - (void) _runInNewThread;
+ (void) setDebug: (int)val; + (void) setDebug: (int)val;
- (void) addLocalObject: (NSDistantObject*)anObj;
- (NSDistantObject*) localForObject: (id)object;
- (void) removeLocalObject: (id)anObj;
- (void) _doneInRmc: (NSPortCoder*)c; - (void) _doneInRmc: (NSPortCoder*)c;
- (NSPortCoder*) _getReplyRmc: (int)sn; - (NSPortCoder*) _getReplyRmc: (int)sn;
- (NSPortCoder*) _makeInRmc: (NSMutableArray*)components; - (NSPortCoder*) _makeInRmc: (NSMutableArray*)components;
@ -318,9 +312,9 @@ setRootObjectForInPort(id anObj, NSPort *aPort)
F_UNLOCK(root_object_map_gate); F_UNLOCK(root_object_map_gate);
} }
static NSMapTable *all_connections_local_objects = NULL; static NSMapTable *objectToCounter = NULL;
static NSMapTable *all_connections_local_targets = NULL; static NSMapTable *targetToCounter = NULL;
static NSMapTable *all_connections_local_cached = NULL; static NSMapTable *targetToCached = NULL;
static NSLock *global_proxies_gate; static NSLock *global_proxies_gate;
@ -438,6 +432,7 @@ static NSLock *global_proxies_gate;
connectionClass = self; connectionClass = self;
dateClass = [NSDate class]; dateClass = [NSDate class];
distantObjectClass = [NSDistantObject class]; distantObjectClass = [NSDistantObject class];
localCounterClass = [GSLocalCounter class];
portCoderClass = [NSPortCoder class]; portCoderClass = [NSPortCoder class];
runLoopClass = [NSRunLoop class]; runLoopClass = [NSRunLoop class];
@ -446,14 +441,14 @@ static NSLock *global_proxies_gate;
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. */
all_connections_local_objects = objectToCounter =
NSCreateMapTable(NSNonOwnedPointerMapKeyCallBacks, NSCreateMapTable(NSNonOwnedPointerMapKeyCallBacks,
NSObjectMapValueCallBacks, 0); NSObjectMapValueCallBacks, 0);
all_connections_local_targets = targetToCounter =
NSCreateMapTable(NSIntMapKeyCallBacks, NSCreateMapTable(NSIntMapKeyCallBacks,
NSNonOwnedPointerMapValueCallBacks, 0); NSNonOwnedPointerMapValueCallBacks, 0);
all_connections_local_cached = targetToCached =
NSCreateMapTable(NSIntMapKeyCallBacks, NSCreateMapTable(NSIntMapKeyCallBacks,
NSObjectMapValueCallBacks, 0); NSObjectMapValueCallBacks, 0);
global_proxies_gate = [NSLock new]; global_proxies_gate = [NSLock new];
@ -510,7 +505,7 @@ static NSLock *global_proxies_gate;
NSArray *cached_locals; NSArray *cached_locals;
int i; int i;
cached_locals = NSAllMapTableValues(all_connections_local_cached); cached_locals = NSAllMapTableValues(targetToCached);
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];
@ -518,7 +513,7 @@ static NSLock *global_proxies_gate;
if ([item countdown] == NO) if ([item countdown] == NO)
{ {
GSLocalCounter *counter = [item obj]; GSLocalCounter *counter = [item obj];
NSMapRemove(all_connections_local_cached, (void*)counter->target); NSMapRemove(targetToCached, (void*)counter->target);
} }
} }
if ([cached_locals count] == 0) if ([cached_locals count] == 0)
@ -710,7 +705,8 @@ static NSLock *global_proxies_gate;
GSIMapInitWithZoneAndCapacity(_localTargets, z, 4); 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)); _remoteProxies = (GSIMapTable)NSZoneMalloc(z, sizeof(GSIMapTable_t));
GSIMapInitWithZoneAndCapacity(_remoteProxies, z, 4); GSIMapInitWithZoneAndCapacity(_remoteProxies, z, 4);
@ -893,7 +889,7 @@ static NSLock *global_proxies_gate;
} }
while (i-- > 0) while (i-- > 0)
{ {
id t = [[targets objectAtIndex: i] localForProxy]; id t = ((ProxyStruct*)[targets objectAtIndex: i])->_object;
[self removeLocalObject: t]; [self removeLocalObject: t];
} }
@ -1846,7 +1842,7 @@ static NSLock *global_proxies_gate;
if (debug_connection > 3) if (debug_connection > 3)
NSLog(@"releasing object with target (0x%x) on (0x%x)", NSLog(@"releasing object with target (0x%x) on (0x%x)",
target, (gsaddr)self); target, (gsaddr)self);
[self removeLocalObject: [prox localForProxy]]; [self removeLocalObject: ((ProxyStruct*)prox)->_object];
} }
else if (debug_connection > 3) else if (debug_connection > 3)
NSLog(@"releasing object with target (0x%x) on (0x%x) - nothing to do", NSLog(@"releasing object with target (0x%x) on (0x%x) - nothing to do",
@ -1878,7 +1874,7 @@ static NSLock *global_proxies_gate;
GSLocalCounter *counter; GSLocalCounter *counter;
M_LOCK(global_proxies_gate); M_LOCK(global_proxies_gate);
counter = NSMapGet (all_connections_local_targets, (void*)target); counter = NSMapGet (targetToCounter, (void*)target);
if (counter == nil) 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 * we move it back from the cache to the main maps so we can
* retain it on this connection. * retain it on this connection.
*/ */
counter = NSMapGet (all_connections_local_cached, (void*)target); counter = NSMapGet (targetToCached, (void*)target);
if (counter) if (counter)
{ {
unsigned t = counter->target; unsigned t = counter->target;
id o = counter->object; id o = counter->object;
NSMapInsert(all_connections_local_objects, (void*)o, counter); NSMapInsert(objectToCounter, (void*)o, counter);
NSMapInsert(all_connections_local_targets, (void*)t, counter); NSMapInsert(targetToCounter, (void*)t, counter);
NSMapRemove(all_connections_local_cached, (void*)t); NSMapRemove(targetToCached, (void*)t);
if (debug_connection > 3) if (debug_connection > 3)
NSLog(@"target (0x%x) moved from cache", target); NSLog(@"target (0x%x) moved from cache", target);
} }
@ -1969,7 +1965,7 @@ static NSLock *global_proxies_gate;
[rmc decodeValueOfObjCType: @encode(unsigned) at: &target]; [rmc decodeValueOfObjCType: @encode(unsigned) at: &target];
[self _doneInRmc: rmc]; [self _doneInRmc: rmc];
p = [self includesLocalTarget: target]; p = [self includesLocalTarget: target];
o = [p localForProxy]; o = ((ProxyStruct*)p)->_object;
/* xxx We should make sure that TARGET is a valid 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. */ /* 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. */ /* Managing objects and proxies. */
- (void) addLocalObject: (id)anObj - (void) addLocalObject: (NSDistantObject*)anObj
{ {
id object = [anObj localForProxy]; id object;
unsigned target; unsigned target;
GSLocalCounter *counter; GSLocalCounter *counter;
GSIMapNode node; GSIMapNode node;
NSParameterAssert (_isValid);
M_LOCK(_proxiesGate); M_LOCK(_proxiesGate);
M_LOCK(global_proxies_gate); M_LOCK(global_proxies_gate);
NSParameterAssert (_isValid);
/* /*
* Record the value in the _localObjects map, retaining it. * Record the value in the _localObjects map, retaining it.
*/ */
object = ((ProxyStruct*)anObj)->_object;
node = GSIMapNodeForKey(_localObjects, (GSIMapKey)object); node = GSIMapNodeForKey(_localObjects, (GSIMapKey)object);
IF_NO_GC(RETAIN(anObj)); IF_NO_GC(RETAIN(anObj));
if (node) if (node == 0)
{ {
RELEASE(node->value.obj); GSIMapAddPair(_localObjects, (GSIMapKey)object, (GSIMapVal)anObj);
node->value.obj = anObj;
} }
else else
{ {
GSIMapAddPair(_localObjects, (GSIMapKey)object, (GSIMapVal)anObj); RELEASE(node->value.obj);
node->value.obj = anObj;
} }
/* /*
* Keep track of local objects accross all connections. * Keep track of local objects accross all connections.
*/ */
counter = NSMapGet(all_connections_local_objects, (void*)object); counter = NSMapGet(objectToCounter, (void*)object);
if (counter) if (counter)
{ {
counter->ref++; counter->ref++;
@ -2282,13 +2277,13 @@ static NSLock *global_proxies_gate;
} }
else else
{ {
counter = [GSLocalCounter newWithObject: object]; counter = [localCounterClass newWithObject: object];
target = counter->target; target = counter->target;
NSMapInsert(all_connections_local_objects, (void*)object, counter); NSMapInsert(objectToCounter, (void*)object, counter);
NSMapInsert(all_connections_local_targets, (void*)target, counter); NSMapInsert(targetToCounter, (void*)target, counter);
RELEASE(counter); RELEASE(counter);
} }
[anObj setProxyTarget: target]; ((ProxyStruct*)anObj)->_handle = target;
GSIMapAddPair(_localTargets, (GSIMapKey)target, (GSIMapVal)anObj); GSIMapAddPair(_localTargets, (GSIMapKey)target, (GSIMapVal)anObj);
if (debug_connection > 2) if (debug_connection > 2)
NSLog(@"add local object (0x%x) target (0x%x) " NSLog(@"add local object (0x%x) target (0x%x) "
@ -2319,19 +2314,6 @@ static NSLock *global_proxies_gate;
return p; 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 - (void) removeLocalObject: (id)anObj
{ {
NSDistantObject *prox; NSDistantObject *prox;
@ -2352,13 +2334,13 @@ static NSLock *global_proxies_gate;
{ {
prox = node->value.obj; prox = node->value.obj;
} }
target = [prox targetForProxy]; target = ((ProxyStruct*)prox)->_handle;
/* /*
* If all references to a local proxy have gone - remove the * If all references to a local proxy have gone - remove the
* global reference as well. * global reference as well.
*/ */
counter = NSMapGet(all_connections_local_objects, (void*)anObj); counter = NSMapGet(objectToCounter, (void*)anObj);
if (counter) if (counter)
{ {
counter->ref--; counter->ref--;
@ -2381,14 +2363,14 @@ static NSLock *global_proxies_gate;
repeats: YES]; repeats: YES];
} }
item = [CachedLocalObject newWithObject: counter time: 30]; item = [CachedLocalObject newWithObject: counter time: 30];
NSMapInsert(all_connections_local_cached, (void*)target, item); NSMapInsert(targetToCached, (void*)target, item);
RELEASE(item); RELEASE(item);
if (debug_connection > 3) if (debug_connection > 3)
NSLog(@"placed local object (0x%x) target (0x%x) in cache", NSLog(@"placed local object (0x%x) target (0x%x) in cache",
(gsaddr)anObj, target); (gsaddr)anObj, target);
} }
NSMapRemove(all_connections_local_objects, (void*)anObj); NSMapRemove(objectToCounter, (void*)anObj);
NSMapRemove(all_connections_local_targets, (void*)target); NSMapRemove(targetToCounter, (void*)target);
} }
} }
@ -2485,10 +2467,11 @@ static NSLock *global_proxies_gate;
- (void) removeProxy: (NSDistantObject*)aProxy - (void) removeProxy: (NSDistantObject*)aProxy
{ {
unsigned target = [aProxy targetForProxy]; unsigned target;
/* Don't assert (_isValid); */ /* Don't assert (_isValid); */
M_LOCK(_proxiesGate); M_LOCK(_proxiesGate);
target = ((ProxyStruct*)aProxy)->_handle;
/* This also releases aProxy */ /* This also releases aProxy */
GSIMapRemoveKey(_remoteProxies, (GSIMapKey)target); GSIMapRemoveKey(_remoteProxies, (GSIMapKey)target);
M_UNLOCK(_proxiesGate); M_UNLOCK(_proxiesGate);
@ -2522,13 +2505,14 @@ static NSLock *global_proxies_gate;
- (void) addProxy: (NSDistantObject*) aProxy - (void) addProxy: (NSDistantObject*) aProxy
{ {
unsigned target = (unsigned int)[aProxy targetForProxy]; unsigned target;
GSIMapNode node; GSIMapNode node;
NSParameterAssert (_isValid); M_LOCK(_proxiesGate);
NSParameterAssert(_isValid);
NSParameterAssert(aProxy->isa == distantObjectClass); NSParameterAssert(aProxy->isa == distantObjectClass);
NSParameterAssert([aProxy connectionForProxy] == self); NSParameterAssert([aProxy connectionForProxy] == self);
M_LOCK(_proxiesGate); target = ((ProxyStruct*)aProxy)->_handle;
node = GSIMapNodeForKey(_remoteProxies, (GSIMapKey)target); node = GSIMapNodeForKey(_remoteProxies, (GSIMapKey)target);
if (node != 0) if (node != 0)
{ {
@ -2612,7 +2596,7 @@ static NSLock *global_proxies_gate;
/* Don't assert (_isValid); */ /* Don't assert (_isValid); */
M_LOCK(global_proxies_gate); M_LOCK(global_proxies_gate);
ret = NSMapGet(all_connections_local_targets, (void*)target); ret = NSMapGet(targetToCounter, (void*)target);
M_UNLOCK(global_proxies_gate); M_UNLOCK(global_proxies_gate);
return ret; return ret;
} }
@ -4504,7 +4488,7 @@ static int messages_received_count;
{ {
timer = [NSTimer scheduledTimerWithTimeInterval: 1.0 timer = [NSTimer scheduledTimerWithTimeInterval: 1.0
target: [NSConnection class] target: [NSConnection class]
selector: @selector(_timeout: ) selector: @selector(_timeout:)
userInfo: nil userInfo: nil
repeats: YES]; repeats: YES];
} }

View file

@ -2148,6 +2148,11 @@ handle_request(int desc)
mcopy(&raddr, rbuf, IASIZE); mcopy(&raddr, rbuf, IASIZE);
mcopy(&laddr, rbuf+IASIZE, 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); mcopy(wbuf+IASIZE, &raddr, IASIZE);
/* /*