ithreading fix

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@23442 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
rfm 2006-09-09 16:55:25 +00:00
parent a94904a806
commit ff19cd1f03
2 changed files with 37 additions and 16 deletions

View file

@ -1,3 +1,10 @@
2006-09-09 Richard Frith-Macdonald <rfm@gnu.org>
* Source/win32/NSMessagePortWin32.m: Restructure to try to avoid
deadlock reported by Wim. Also implement -release to remove port
from name table so that another thread can't find it in the window
between checking the refcount end deallocation.
2006-09-07 Richard Frith-Macdonald <rfm@gnu.org> 2006-09-07 Richard Frith-Macdonald <rfm@gnu.org>
* Headers/Foundation/NSObject.h: Fix incorrect backward compatibility * Headers/Foundation/NSObject.h: Fix incorrect backward compatibility

View file

@ -203,11 +203,13 @@ static Class messagePortClass = 0;
{ {
p = [[self alloc] initWithName: name]; p = [[self alloc] initWithName: name];
} }
else
{
[p _setupSendPort];
}
M_UNLOCK(messagePortLock); M_UNLOCK(messagePortLock);
if ([self _setupSendPort] == NO)
{
NSLog(@"unable to access mailslot '%@' - %s",
p->name, GSLastErrorStr(errno));
DESTROY(p);
}
return p; return p;
} }
@ -382,22 +384,12 @@ static Class messagePortClass = 0;
this->wHandle = INVALID_HANDLE_VALUE; this->wHandle = INVALID_HANDLE_VALUE;
this->wEvent = INVALID_HANDLE_VALUE; this->wEvent = INVALID_HANDLE_VALUE;
if ([self _setupSendPort] == NO)
{
NSLog(@"unable to access mailslot '%@' - %s",
this->name, GSLastErrorStr(errno));
DESTROY(self);
}
else
{
NSMapInsert(ports, (void*)this->name, (void*)self); NSMapInsert(ports, (void*)this->name, (void*)self);
NSDebugMLLog(@"NSMessagePort", @"Created speaking port: %@", self); NSDebugMLLog(@"NSMessagePort", @"Created speaking port: %@", self);
} }
}
else else
{ {
RELEASE(self); RELEASE(self);
[p _setupSendPort];
self = p; self = p;
} }
M_UNLOCK(messagePortLock); M_UNLOCK(messagePortLock);
@ -935,6 +927,28 @@ again:
return sizeof(GSPortItemHeader) + sizeof(GSPortMsgHeader); return sizeof(GSPortItemHeader) + sizeof(GSPortMsgHeader);
} }
- (void) release
{
/* We lock the port table while checking, to prevent
* another thread from grabbing this port while we are
* checking it.
* If we are going to deallocate the object, we first remove
* it from the table so that no other thread will find it
* and try to use it while it is being deallocated.
*/
M_LOCK(messagePortLock);
if (NSDecrementExtraRefCountWasZero(self))
{
NSMapRemove(ports, (void*)this->name);
M_UNLOCK(messagePortLock);
[self dealloc];
}
else
{
M_UNLOCK(messagePortLock);
}
}
- (BOOL) sendBeforeDate: (NSDate*)when - (BOOL) sendBeforeDate: (NSDate*)when
msgid: (int)msgId msgid: (int)msgId
components: (NSMutableArray*)components components: (NSMutableArray*)components