Thread safety fix

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@23445 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
rfm 2006-09-10 10:47:50 +00:00
parent e3532b5295
commit bdf6b69bce
3 changed files with 62 additions and 15 deletions

View file

@ -2,6 +2,11 @@
* Source/NSTimeZone.m: Remove unnecessary check on fiel name as * Source/NSTimeZone.m: Remove unnecessary check on fiel name as
Roland Schwingel reported that it caught legitimate files on windows. Roland Schwingel reported that it caught legitimate files on windows.
* Source/NSMessagePort.m:
* Source/NSSocketPort.m:
Protect -release with lock and remove port from gloibal table within
protected region, to avoid possible double deallocation in a
multithreaded process.
2006-09-09 Richard Frith-Macdonald <rfm@gnu.org> 2006-09-09 Richard Frith-Macdonald <rfm@gnu.org>

View file

@ -1574,14 +1574,14 @@ typedef struct {
unsigned i; unsigned i;
M_LOCK(messagePortLock); M_LOCK(messagePortLock);
NSMapRemove(messagePortMap, (void*)name);
M_UNLOCK(messagePortLock);
if (lDesc >= 0) if (lDesc >= 0)
{ {
(void) close(lDesc); (void) close(lDesc);
unlink([name bytes]); unlink([name bytes]);
lDesc = -1; lDesc = -1;
} }
NSMapRemove(messagePortMap, (void*)name);
M_UNLOCK(messagePortLock);
if (handles != 0) if (handles != 0)
{ {
@ -1691,6 +1691,21 @@ typedef struct {
} }
} }
- (void) release
{
M_LOCK(messagePortLock);
if (NSDecrementExtraRefCountWasZero(self))
{
NSMapRemove(messagePortMap, (void*)name);
M_UNLOCK(messagePortLock);
[self dealloc];
}
else
{
M_UNLOCK(messagePortLock);
}
}
- (void) removeHandle: (GSMessageHandle*)handle - (void) removeHandle: (GSMessageHandle*)handle
{ {
M_LOCK(myLock); M_LOCK(myLock);

View file

@ -18,7 +18,8 @@
You should have received a copy of the GNU Library General Public You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free License along with this library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02111 USA.
*/ */
#include "config.h" #include "config.h"
@ -1693,7 +1694,8 @@ static Class tcpPortClass;
NSLog(@"Invalid Event - '%d'", WSAGetLastError()); NSLog(@"Invalid Event - '%d'", WSAGetLastError());
abort(); abort();
} }
rc = WSAEventSelect(port->listener, port->eventListener, FD_ACCEPT); rc = WSAEventSelect(port->listener,
port->eventListener, FD_ACCEPT);
NSAssert(rc == 0, @"WSAEventSelect failed!"); NSAssert(rc == 0, @"WSAEventSelect failed!");
#endif #endif
/* /*
@ -1725,7 +1727,8 @@ static Class tcpPortClass;
* Make sure we have the map table for this port. * Make sure we have the map table for this port.
*/ */
port->portNum = number; port->portNum = number;
thePorts = (NSMapTable*)NSMapGet(tcpPortMap, (void*)(uintptr_t)number); thePorts
= (NSMapTable*)NSMapGet(tcpPortMap, (void*)(uintptr_t)number);
if (thePorts == 0) if (thePorts == 0)
{ {
/* /*
@ -1734,7 +1737,8 @@ static Class tcpPortClass;
*/ */
thePorts = NSCreateMapTable(NSIntMapKeyCallBacks, thePorts = NSCreateMapTable(NSIntMapKeyCallBacks,
NSNonOwnedPointerMapValueCallBacks, 0); NSNonOwnedPointerMapValueCallBacks, 0);
NSMapInsert(tcpPortMap, (void*)(uintptr_t)number, (void*)thePorts); NSMapInsert(tcpPortMap,
(void*)(uintptr_t)number, (void*)thePorts);
} }
/* /*
* Record the port by host. * Record the port by host.
@ -2057,6 +2061,10 @@ static Class tcpPortClass;
thePorts = NSMapGet(tcpPortMap, (void*)(uintptr_t)portNum); thePorts = NSMapGet(tcpPortMap, (void*)(uintptr_t)portNum);
if (thePorts != 0) if (thePorts != 0)
{ {
NSMapRemove(thePorts, (void*)host);
}
M_UNLOCK(tcpPortLock);
if (listener >= 0) if (listener >= 0)
{ {
(void) close(listener); (void) close(listener);
@ -2066,9 +2074,6 @@ static Class tcpPortClass;
eventListener = WSA_INVALID_EVENT; eventListener = WSA_INVALID_EVENT;
#endif #endif
} }
NSMapRemove(thePorts, (void*)host);
}
M_UNLOCK(tcpPortLock);
if (handles != 0) if (handles != 0)
{ {
@ -2216,6 +2221,28 @@ static Class tcpPortClass;
} }
} }
- (void) release
{
M_LOCK(tcpPortLock);
if (NSDecrementExtraRefCountWasZero(self))
{
NSMapTable *thePorts;
thePorts = NSMapGet(tcpPortMap, (void*)(uintptr_t)portNum);
if (thePorts != 0)
{
NSMapRemove(thePorts, host);
}
M_UNLOCK(tcpPortLock);
[self dealloc];
}
else
{
M_UNLOCK(tcpPortLock);
}
}
/* /*
* This is called when a tcp/ip socket connection is broken. We remove the * This is called when a tcp/ip socket connection is broken. We remove the
* connection handle from this port and, if this was the last handle to a * connection handle from this port and, if this was the last handle to a