Fix leak of handled when using DO between threads.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@19910 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
CaS 2004-08-24 08:08:14 +00:00
parent 0d8ec1ee0f
commit 71a8c69719
5 changed files with 102 additions and 23 deletions

View file

@ -5,6 +5,13 @@
* Source/NSIndexSet.m: ([getIndexes:maxCount:inIndexRange:]) accept * Source/NSIndexSet.m: ([getIndexes:maxCount:inIndexRange:]) accept
null pointer for index range. Consistent with undocumented MacOS-X null pointer for index range. Consistent with undocumented MacOS-X
feature (but we document it). feature (but we document it).
* Headers/Additions/GNUstepBase/DistributedObjects.h:
* Source/NSConnection.m:
* Source/NSMessagePort.m:
* Source/NSSocketPort.m: Use new ([-conversation:]) method to
obtain handle for specific network link in use by a connection,
and invalidate it when the connection is iunvaliodated.
Fixes bug #9798
2004-08-23 Richard Frith-Macdonald <rfm@gnu.org> 2004-08-23 Richard Frith-Macdonald <rfm@gnu.org>

View file

@ -25,7 +25,7 @@
#define __DistributedObjects_h #define __DistributedObjects_h
/* /*
* For internal use by the GNUstep base library. * For <strong>INTERNAL</strong> use by the GNUstep base library.
* This file should not be installed. The only reason why it is * This file should not be installed. The only reason why it is
* located here, is to allow target specific headers (like mframe.h), * located here, is to allow target specific headers (like mframe.h),
* which are located according to dis/enabled-flattened, * which are located according to dis/enabled-flattened,
@ -43,10 +43,7 @@
#include <Foundation/NSConnection.h> #include <Foundation/NSConnection.h>
#include <Foundation/NSDistantObject.h> #include <Foundation/NSDistantObject.h>
#include <Foundation/NSPortCoder.h> #include <Foundation/NSPortCoder.h>
#include <Foundation/NSPort.h>
@class NSDistantObject;
@class NSConnection;
@class NSPort;
/* /*
* Distributed Objects identifiers * Distributed Objects identifiers
@ -79,6 +76,10 @@ enum {
- (void) retainTarget: (unsigned)target; - (void) retainTarget: (unsigned)target;
@end @end
@interface NSPort (Internal)
- (id) conversation: (NSPort*)receivePort;
@end
/* /*
* A structure for passing context information using in encoding/decoding * A structure for passing context information using in encoding/decoding
* arguments for DO * arguments for DO

View file

@ -434,12 +434,11 @@ static NSLock *cached_proxies_gate = nil;
} }
/** /**
* Not used in GNUstep * Return the current conversation ... not implemented in GNUstep
*/ */
+ (id) currentConversation + (id) currentConversation
{ {
[self notImplemented: _cmd]; return nil;
return self;
} }
/** /**
@ -1104,6 +1103,14 @@ static NSLock *cached_proxies_gate = nil;
} }
#endif #endif
/*
* Invalidate the current conversation so we don't leak.
*/
if ([_sendPort isValid] == YES)
{
[[_sendPort conversation: _receivePort] invalidate];
}
RELEASE(self); RELEASE(self);
} }
@ -1258,7 +1265,7 @@ static NSLock *cached_proxies_gate = nil;
} }
/** /**
* Removes mode from the run loop modes used to recieve incoming messages. * Removes mode from the run loop modes used to receive incoming messages.
*/ */
- (void) removeRequestMode: (NSString*)mode - (void) removeRequestMode: (NSString*)mode
{ {

View file

@ -556,7 +556,8 @@ static Class runLoopClass;
extra: (void*)extra extra: (void*)extra
forMode: (NSString*)mode forMode: (NSString*)mode
{ {
NSDebugMLLog(@"NSMessagePort_details", @"received %s event on 0x%x in thread 0x%x", NSDebugMLLog(@"NSMessagePort_details",
@"received %s event on 0x%x in thread 0x%x",
type == ET_RPORT ? "read" : "write", self, GSCurrentThread()); type == ET_RPORT ? "read" : "write", self, GSCurrentThread());
/* /*
* If we have been invalidated (desc < 0) then we should ignore this * If we have been invalidated (desc < 0) then we should ignore this
@ -641,7 +642,8 @@ static Class runLoopClass;
} }
res = 0; /* Interrupted - continue */ res = 0; /* Interrupted - continue */
} }
NSDebugMLLog(@"NSMessagePort_details", @"read %d bytes on 0x%x in thread 0x%x", NSDebugMLLog(@"NSMessagePort_details",
@"read %d bytes on 0x%x in thread 0x%x",
res, self, GSCurrentThread()); res, self, GSCurrentThread());
rLength += res; rLength += res;
@ -751,7 +753,8 @@ static Class runLoopClass;
} }
else else
{ {
NSLog(@"%@ - bad data received on port handle, rType=%i", self, rType); NSLog(@"%@ - bad data received on port handle, rType=%i",
self, rType);
M_UNLOCK(myLock); M_UNLOCK(myLock);
[self invalidate]; [self invalidate];
return; return;
@ -1233,7 +1236,10 @@ static int unique_index = 0;
{ {
unsigned i; unsigned i;
NSMessagePort *port = nil; NSMessagePort *port = nil;
NSData *theName = [[NSData alloc] initWithBytes: socketName length: strlen(socketName)+1]; NSData *theName;
theName = [[NSData alloc] initWithBytes: socketName
length: strlen(socketName)+1];
M_LOCK(messagePortLock); M_LOCK(messagePortLock);
@ -1307,7 +1313,8 @@ static int unique_index = 0;
* Make sure we have the map table for this port. * Make sure we have the map table for this port.
*/ */
NSMapInsert(messagePortMap, (void*)theName, (void*)port); NSMapInsert(messagePortMap, (void*)theName, (void*)port);
NSDebugMLLog(@"NSMessagePort", @"Created listening port: %@", port); NSDebugMLLog(@"NSMessagePort", @"Created listening port: %@",
port);
} }
} }
else else
@ -1421,7 +1428,34 @@ static int unique_index = 0;
M_UNLOCK(myLock); M_UNLOCK(myLock);
} }
- (GSMessageHandle*) handleForPort: (NSMessagePort*)recvPort beforeDate: (NSDate*)when - (id) conversation: (NSPort*)recvPort
{
NSMapEnumerator me;
int sock;
GSMessageHandle *handle = nil;
M_LOCK(myLock);
/*
* Enumerate all our socket handles, and look for one with port.
*/
me = NSEnumerateMapTable(handles);
while (NSNextMapEnumeratorPair(&me, (void*)&sock, (void*)&handle))
{
if ([handle recvPort] == recvPort)
{
RETAIN(handle);
NSEndMapTableEnumeration(&me);
M_UNLOCK(myLock);
return AUTORELEASE(handle);
}
}
NSEndMapTableEnumeration(&me);
M_UNLOCK(myLock);
return nil;
}
- (GSMessageHandle*) handleForPort: (NSMessagePort*)recvPort
beforeDate: (NSDate*)when
{ {
NSMapEnumerator me; NSMapEnumerator me;
int sock; int sock;
@ -1496,7 +1530,8 @@ static int unique_index = 0;
if (d == nil) if (d == nil)
{ {
NSDebugMLLog(@"NSMessagePort", @"No delegate to handle incoming message", 0); NSDebugMLLog(@"NSMessagePort",
@"No delegate to handle incoming message", 0);
return; return;
} }
if ([d respondsToSelector: @selector(handlePortMessage:)] == NO) if ([d respondsToSelector: @selector(handlePortMessage:)] == NO)
@ -1546,8 +1581,9 @@ static int unique_index = 0;
i = [handleArray count]; i = [handleArray count];
while (i-- > 0) while (i-- > 0)
{ {
GSMessageHandle *handle = [handleArray objectAtIndex: i]; GSMessageHandle *handle;
handle = [handleArray objectAtIndex: i];
[handle invalidate]; [handle invalidate];
} }
/* /*
@ -1598,7 +1634,8 @@ static int unique_index = 0;
desc = accept(listener, (struct sockaddr*)&sockAddr, &size); desc = accept(listener, (struct sockaddr*)&sockAddr, &size);
if (desc < 0) if (desc < 0)
{ {
NSDebugMLLog(@"NSMessagePort", @"accept failed - handled in other thread?"); NSDebugMLLog(@"NSMessagePort",
@"accept failed - handled in other thread?");
} }
else else
{ {

View file

@ -1624,7 +1624,34 @@ static unsigned wordAlign;
M_UNLOCK(myLock); M_UNLOCK(myLock);
} }
- (GSTcpHandle*) handleForPort: (NSSocketPort*)recvPort beforeDate: (NSDate*)when - (id) conversation: (NSPort*)recvPort
{
NSMapEnumerator me;
SOCKET sock;
GSTcpHandle *handle = nil;
M_LOCK(myLock);
/*
* Enumerate all our socket handles, and look for one with port.
*/
me = NSEnumerateMapTable(handles);
while (NSNextMapEnumeratorPair(&me, (void*)&sock, (void*)&handle))
{
if ([handle recvPort] == recvPort)
{
RETAIN(handle);
NSEndMapTableEnumeration(&me);
M_UNLOCK(myLock);
return AUTORELEASE(handle);
}
}
NSEndMapTableEnumeration(&me);
M_UNLOCK(myLock);
return nil;
}
- (GSTcpHandle*) handleForPort: (NSSocketPort*)recvPort
beforeDate: (NSDate*)when
{ {
NSMapEnumerator me; NSMapEnumerator me;
SOCKET sock; SOCKET sock;