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
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>

View file

@ -1574,14 +1574,14 @@ typedef struct {
unsigned i;
M_LOCK(messagePortLock);
NSMapRemove(messagePortMap, (void*)name);
M_UNLOCK(messagePortLock);
if (lDesc >= 0)
{
(void) close(lDesc);
unlink([name bytes]);
lDesc = -1;
}
NSMapRemove(messagePortMap, (void*)name);
M_UNLOCK(messagePortLock);
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
{
M_LOCK(myLock);

View file

@ -18,7 +18,8 @@
You should have received a copy of the GNU Library General Public
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"
@ -1693,7 +1694,8 @@ static Class tcpPortClass;
NSLog(@"Invalid Event - '%d'", WSAGetLastError());
abort();
}
rc = WSAEventSelect(port->listener, port->eventListener, FD_ACCEPT);
rc = WSAEventSelect(port->listener,
port->eventListener, FD_ACCEPT);
NSAssert(rc == 0, @"WSAEventSelect failed!");
#endif
/*
@ -1725,7 +1727,8 @@ static Class tcpPortClass;
* Make sure we have the map table for this port.
*/
port->portNum = number;
thePorts = (NSMapTable*)NSMapGet(tcpPortMap, (void*)(uintptr_t)number);
thePorts
= (NSMapTable*)NSMapGet(tcpPortMap, (void*)(uintptr_t)number);
if (thePorts == 0)
{
/*
@ -1734,7 +1737,8 @@ static Class tcpPortClass;
*/
thePorts = NSCreateMapTable(NSIntMapKeyCallBacks,
NSNonOwnedPointerMapValueCallBacks, 0);
NSMapInsert(tcpPortMap, (void*)(uintptr_t)number, (void*)thePorts);
NSMapInsert(tcpPortMap,
(void*)(uintptr_t)number, (void*)thePorts);
}
/*
* Record the port by host.
@ -2057,19 +2061,20 @@ static Class tcpPortClass;
thePorts = NSMapGet(tcpPortMap, (void*)(uintptr_t)portNum);
if (thePorts != 0)
{
if (listener >= 0)
{
(void) close(listener);
listener = -1;
#if defined(__MINGW32__)
WSACloseEvent(eventListener);
eventListener = WSA_INVALID_EVENT;
#endif
}
NSMapRemove(thePorts, (void*)host);
}
M_UNLOCK(tcpPortLock);
if (listener >= 0)
{
(void) close(listener);
listener = -1;
#if defined(__MINGW32__)
WSACloseEvent(eventListener);
eventListener = WSA_INVALID_EVENT;
#endif
}
if (handles != 0)
{
handleArray = NSAllMapTableValues(handles);
@ -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
* connection handle from this port and, if this was the last handle to a