mirror of
https://github.com/gnustep/libs-base.git
synced 2025-06-02 09:31:07 +00:00
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:
parent
0d8ec1ee0f
commit
71a8c69719
5 changed files with 102 additions and 23 deletions
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue