mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-31 16:50:58 +00:00
Thread safety issues addressed
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@8130 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
7a672f22fe
commit
ce72dc7261
2 changed files with 72 additions and 35 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
2000-11-16 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
|
* Source/GSTcpPort.m: Altered all GSTcpHandle debug output to include
|
||||||
|
current thread. Added locking for read/write operations on handle.
|
||||||
|
Hopefully all thread-safe now :-)
|
||||||
|
|
||||||
2000-11-15 Richard Frith-Macdonald <rfm@gnu.org>
|
2000-11-15 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
* Source/NSConnection.m: ([-_getReplyRmc:]) added semi-busy wait
|
* Source/NSConnection.m: ([-_getReplyRmc:]) added semi-busy wait
|
||||||
|
|
|
@ -451,7 +451,8 @@ static Class runLoopClass;
|
||||||
BOOL gotAddr = NO;
|
BOOL gotAddr = NO;
|
||||||
NSRunLoop *l;
|
NSRunLoop *l;
|
||||||
|
|
||||||
NSDebugMLLog(@"GSTcpHandle", @"Connecting before %@", when);
|
NSDebugMLLog(@"GSTcpHandle", @"Connecting on 0x%x in thread 0x%x before %@",
|
||||||
|
self, GSCurrentThread(), when);
|
||||||
if (state != GS_H_UNCON)
|
if (state != GS_H_UNCON)
|
||||||
{
|
{
|
||||||
NSLog(@"attempting connect on connected handle");
|
NSLog(@"attempting connect on connected handle");
|
||||||
|
@ -596,6 +597,8 @@ static Class runLoopClass;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Method to pass an incoming message to the recieving port.
|
* Method to pass an incoming message to the recieving port.
|
||||||
|
* Our lock must be locked on entry to this method, and we
|
||||||
|
* unlock it temporarily while actually sending the message.
|
||||||
*/
|
*/
|
||||||
- (void) dispatch
|
- (void) dispatch
|
||||||
{
|
{
|
||||||
|
@ -609,9 +612,14 @@ static Class runLoopClass;
|
||||||
[pm setMsgid: rId];
|
[pm setMsgid: rId];
|
||||||
rId = 0;
|
rId = 0;
|
||||||
DESTROY(rItems);
|
DESTROY(rItems);
|
||||||
NSDebugMLLog(@"GSTcpHandle", @"got message %@", pm);
|
NSDebugMLLog(@"GSTcpHandle", @"got message %@ on 0x%x in thread 0x%x",
|
||||||
|
pm, self, GSCurrentThread());
|
||||||
|
RETAIN(rp);
|
||||||
|
DO_UNLOCK(myLock);
|
||||||
[rp handlePortMessage: pm];
|
[rp handlePortMessage: pm];
|
||||||
|
DO_LOCK(myLock);
|
||||||
RELEASE(pm);
|
RELEASE(pm);
|
||||||
|
RELEASE(rp);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) gcFinalize
|
- (void) gcFinalize
|
||||||
|
@ -642,7 +650,8 @@ static Class runLoopClass;
|
||||||
type: ET_EDESC
|
type: ET_EDESC
|
||||||
forMode: nil
|
forMode: nil
|
||||||
all: YES];
|
all: YES];
|
||||||
NSDebugMLLog(@"GSTcpHandle", @"invalidated", 0);
|
NSDebugMLLog(@"GSTcpHandle", @"invalidated 0x%x in thread 0x%x",
|
||||||
|
self, GSCurrentThread());
|
||||||
[[self recvPort] removeHandle: self];
|
[[self recvPort] removeHandle: self];
|
||||||
[[self sendPort] removeHandle: self];
|
[[self sendPort] removeHandle: self];
|
||||||
}
|
}
|
||||||
|
@ -667,8 +676,8 @@ static Class runLoopClass;
|
||||||
extra: (void*)extra
|
extra: (void*)extra
|
||||||
forMode: (NSString*)mode
|
forMode: (NSString*)mode
|
||||||
{
|
{
|
||||||
NSDebugMLLog(@"GSTcpHandle", @"received %s event on 0x%x",
|
NSDebugMLLog(@"GSTcpHandle", @"received %s event on 0x%x in thread 0x%x",
|
||||||
type == ET_RPORT ? "read" : "write", self);
|
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
|
||||||
* event and remove ourself from the runloop.
|
* event and remove ourself from the runloop.
|
||||||
|
@ -684,6 +693,8 @@ static Class runLoopClass;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DO_LOCK(myLock);
|
||||||
|
|
||||||
if (type == ET_RPORT)
|
if (type == ET_RPORT)
|
||||||
{
|
{
|
||||||
unsigned want;
|
unsigned want;
|
||||||
|
@ -725,20 +736,25 @@ static Class runLoopClass;
|
||||||
{
|
{
|
||||||
if (res == 0)
|
if (res == 0)
|
||||||
{
|
{
|
||||||
NSDebugMLLog(@"GSTcpHandle", @"read attempt failed - eof", 0);
|
NSDebugMLLog(@"GSTcpHandle", @"read eof on 0x%x in thread 0x%x",
|
||||||
|
self, GSCurrentThread());
|
||||||
|
DO_UNLOCK(myLock);
|
||||||
[self invalidate];
|
[self invalidate];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (errno != EINTR && errno != EAGAIN)
|
else if (errno != EINTR && errno != EAGAIN)
|
||||||
{
|
{
|
||||||
NSDebugMLLog(@"GSTcpHandle", @"read attempt failed - %s",
|
NSDebugMLLog(@"GSTcpHandle",
|
||||||
strerror(errno));
|
@"read failed - %s on 0x%x in thread 0x%x",
|
||||||
|
strerror(errno), self, GSCurrentThread());
|
||||||
|
DO_UNLOCK(myLock);
|
||||||
[self invalidate];
|
[self invalidate];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
res = 0; /* Interrupted - continue */
|
res = 0; /* Interrupted - continue */
|
||||||
}
|
}
|
||||||
NSDebugMLLog(@"GSTcpHandle", @"read %d bytes", res);
|
NSDebugMLLog(@"GSTcpHandle", @"read %d bytes on 0x%x in thread 0x%x",
|
||||||
|
res, self, GSCurrentThread());
|
||||||
rLength += res;
|
rLength += res;
|
||||||
|
|
||||||
while (valid == YES && rLength >= rWant)
|
while (valid == YES && rLength >= rWant)
|
||||||
|
@ -759,10 +775,11 @@ static Class runLoopClass;
|
||||||
l = GSSwapBigI32ToHost(h->length);
|
l = GSSwapBigI32ToHost(h->length);
|
||||||
if (rType == GSP_PORT)
|
if (rType == GSP_PORT)
|
||||||
{
|
{
|
||||||
if (l > 32)
|
if (l > 128)
|
||||||
{
|
{
|
||||||
NSLog(@"%@ - unreasonable length (%u) for port",
|
NSLog(@"%@ - unreasonable length (%u) for port",
|
||||||
self, l);
|
self, l);
|
||||||
|
DO_UNLOCK(myLock);
|
||||||
[self invalidate];
|
[self invalidate];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -795,6 +812,7 @@ static Class runLoopClass;
|
||||||
if (nItems == [rItems count])
|
if (nItems == [rItems count])
|
||||||
{
|
{
|
||||||
[self dispatch];
|
[self dispatch];
|
||||||
|
bytes = [rData mutableBytes];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -803,6 +821,7 @@ static Class runLoopClass;
|
||||||
{
|
{
|
||||||
NSLog(@"%@ - unreasonable length (%u) for data",
|
NSLog(@"%@ - unreasonable length (%u) for data",
|
||||||
self, l);
|
self, l);
|
||||||
|
DO_UNLOCK(myLock);
|
||||||
[self invalidate];
|
[self invalidate];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -825,6 +844,7 @@ static Class runLoopClass;
|
||||||
{
|
{
|
||||||
NSLog(@"%@ - unreasonable length (%u) for data",
|
NSLog(@"%@ - unreasonable length (%u) for data",
|
||||||
self, l);
|
self, l);
|
||||||
|
DO_UNLOCK(myLock);
|
||||||
[self invalidate];
|
[self invalidate];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -843,6 +863,7 @@ static Class runLoopClass;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NSLog(@"%@ - bad data received on port handle", self);
|
NSLog(@"%@ - bad data received on port handle", self);
|
||||||
|
DO_UNLOCK(myLock);
|
||||||
[self invalidate];
|
[self invalidate];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -889,6 +910,7 @@ static Class runLoopClass;
|
||||||
if (nItems == 1)
|
if (nItems == 1)
|
||||||
{
|
{
|
||||||
[self dispatch];
|
[self dispatch];
|
||||||
|
bytes = [rData mutableBytes];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -924,6 +946,7 @@ static Class runLoopClass;
|
||||||
if (nItems == [rItems count])
|
if (nItems == [rItems count])
|
||||||
{
|
{
|
||||||
[self dispatch];
|
[self dispatch];
|
||||||
|
bytes = [rData mutableBytes];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -963,6 +986,7 @@ static Class runLoopClass;
|
||||||
if (nItems == [rItems count])
|
if (nItems == [rItems count])
|
||||||
{
|
{
|
||||||
[self dispatch];
|
[self dispatch];
|
||||||
|
bytes = [rData mutableBytes];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -972,7 +996,6 @@ static Class runLoopClass;
|
||||||
}
|
}
|
||||||
else if (type == ET_WDESC)
|
else if (type == ET_WDESC)
|
||||||
{
|
{
|
||||||
DO_LOCK(myLock);
|
|
||||||
if (state == GS_H_TRYCON) /* Connection attempt. */
|
if (state == GS_H_TRYCON) /* Connection attempt. */
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
@ -994,7 +1017,9 @@ static Class runLoopClass;
|
||||||
RELEASE(defaultAddress);
|
RELEASE(defaultAddress);
|
||||||
defaultAddress = RETAIN([NSString stringWithCString:
|
defaultAddress = RETAIN([NSString stringWithCString:
|
||||||
inet_ntoa(sockAddr.sin_addr)]);
|
inet_ntoa(sockAddr.sin_addr)]);
|
||||||
NSDebugMLLog(@"GSTcpHandle", @"wrote %d bytes", len);
|
NSDebugMLLog(@"GSTcpHandle",
|
||||||
|
@"wrote %d bytes on 0x%x in thread 0x%x",
|
||||||
|
len, self, GSCurrentThread());
|
||||||
state = GS_H_CONNECTED;
|
state = GS_H_CONNECTED;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1041,8 +1066,9 @@ static Class runLoopClass;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NSDebugMLLog(@"GSTcpHandle", @"wrote %d bytes on 0x%x",
|
NSDebugMLLog(@"GSTcpHandle",
|
||||||
res, self);
|
@"wrote %d bytes on 0x%x in thread 0x%x",
|
||||||
|
res, self, GSCurrentThread());
|
||||||
wLength += res;
|
wLength += res;
|
||||||
if (wLength == l)
|
if (wLength == l)
|
||||||
{
|
{
|
||||||
|
@ -1068,8 +1094,9 @@ static Class runLoopClass;
|
||||||
/*
|
/*
|
||||||
* message completed - remove from list.
|
* message completed - remove from list.
|
||||||
*/
|
*/
|
||||||
NSDebugMLLog(@"GSTcpHandle", @"completed 0x%x on 0x%x",
|
NSDebugMLLog(@"GSTcpHandle",
|
||||||
components, self);
|
@"completed 0x%x on 0x%x in thread 0x%x",
|
||||||
|
components, self, GSCurrentThread());
|
||||||
wData = nil;
|
wData = nil;
|
||||||
wItem = 0;
|
wItem = 0;
|
||||||
[wMsgs removeObjectAtIndex: 0];
|
[wMsgs removeObjectAtIndex: 0];
|
||||||
|
@ -1082,8 +1109,9 @@ static Class runLoopClass;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DO_UNLOCK(myLock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DO_UNLOCK(myLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL) sendMessage: (NSArray*)components beforeDate: (NSDate*)when
|
- (BOOL) sendMessage: (NSArray*)components beforeDate: (NSDate*)when
|
||||||
|
@ -1092,8 +1120,9 @@ static Class runLoopClass;
|
||||||
BOOL sent = NO;
|
BOOL sent = NO;
|
||||||
|
|
||||||
NSAssert([components count] > 0, NSInternalInconsistencyException);
|
NSAssert([components count] > 0, NSInternalInconsistencyException);
|
||||||
NSDebugMLLog(@"GSTcpHandle", @"Sending message 0x%x %@ on 0x%x(%d) before %@",
|
NSDebugMLLog(@"GSTcpHandle",
|
||||||
components, components, self, desc, when);
|
@"Sending message 0x%x %@ on 0x%x(%d) in thread 0x%x before %@",
|
||||||
|
components, components, self, desc, GSCurrentThread(), when);
|
||||||
[wMsgs addObject: components];
|
[wMsgs addObject: components];
|
||||||
|
|
||||||
l = [runLoopClass currentRunLoop];
|
l = [runLoopClass currentRunLoop];
|
||||||
|
@ -1118,8 +1147,9 @@ static Class runLoopClass;
|
||||||
sent = YES;
|
sent = YES;
|
||||||
}
|
}
|
||||||
RELEASE(self);
|
RELEASE(self);
|
||||||
NSDebugMLLog(@"GSTcpHandle", @"Message send 0x%x on 0x%x status %d",
|
NSDebugMLLog(@"GSTcpHandle",
|
||||||
components, self, sent);
|
@"Message send 0x%x on 0x%x in thread 0x%x status %d",
|
||||||
|
components, self, GSCurrentThread(), sent);
|
||||||
return sent;
|
return sent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1725,7 +1755,6 @@ static Class tcpPortClass;
|
||||||
int desc = (int)(gsaddr)extra;
|
int desc = (int)(gsaddr)extra;
|
||||||
GSTcpHandle *handle;
|
GSTcpHandle *handle;
|
||||||
|
|
||||||
|
|
||||||
if (desc == listener)
|
if (desc == listener)
|
||||||
{
|
{
|
||||||
struct sockaddr_in sockAddr;
|
struct sockaddr_in sockAddr;
|
||||||
|
@ -1734,21 +1763,23 @@ static Class tcpPortClass;
|
||||||
desc = accept(listener, (struct sockaddr*)&sockAddr, &size);
|
desc = accept(listener, (struct sockaddr*)&sockAddr, &size);
|
||||||
if (desc < 0)
|
if (desc < 0)
|
||||||
{
|
{
|
||||||
[NSException raise: NSInternalInconsistencyException
|
NSDebugMLLog(@"NSPort", @"accept failed - handled in other thread?");
|
||||||
format: @"GSTcpPort accept(): %s", strerror(errno)];
|
|
||||||
}
|
}
|
||||||
/*
|
else
|
||||||
* Create a handle for the socket and set it up so we are its
|
{
|
||||||
* receiving port, and it's waiting to get the port name from
|
/*
|
||||||
* the other end.
|
* Create a handle for the socket and set it up so we are its
|
||||||
*/
|
* receiving port, and it's waiting to get the port name from
|
||||||
handle = [GSTcpHandle handleWithDescriptor: desc];
|
* the other end.
|
||||||
memcpy(&handle->sockAddr, &sockAddr, sizeof(sockAddr));
|
*/
|
||||||
handle->defaultAddress = RETAIN([NSString stringWithCString:
|
handle = [GSTcpHandle handleWithDescriptor: desc];
|
||||||
inet_ntoa(sockAddr.sin_addr)]);
|
memcpy(&handle->sockAddr, &sockAddr, sizeof(sockAddr));
|
||||||
|
handle->defaultAddress = RETAIN([NSString stringWithCString:
|
||||||
|
inet_ntoa(sockAddr.sin_addr)]);
|
||||||
|
|
||||||
[handle setState: GS_H_ACCEPT];
|
[handle setState: GS_H_ACCEPT];
|
||||||
[self addHandle: handle forSend: NO];
|
[self addHandle: handle forSend: NO];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue