mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-25 01:31:08 +00:00
try to make thread synchronisation I/O cleaner and perhaps safer if we do
something like run out of file descriptors for the pipe. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@38153 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
092d48d2f8
commit
18ef693dec
2 changed files with 36 additions and 7 deletions
|
@ -1,3 +1,10 @@
|
|||
2014-11-04 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Source/NSThread.m: When handling perform in another thread, check
|
||||
more carefully for inter-thread communications (pipe on unix, event
|
||||
on windows) and make sure we invalidate performers safely outside
|
||||
the lock protected region when I/O is complete.
|
||||
|
||||
2014-11-01 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Source/GSHTTPURLHandle.m: Fix leak of handle when starting a new
|
||||
|
|
|
@ -897,12 +897,20 @@ static void *nsthreadLauncher(void* thread)
|
|||
@implementation GSRunLoopThreadInfo
|
||||
- (void) addPerformer: (id)performer
|
||||
{
|
||||
BOOL signalled = NO;
|
||||
|
||||
[lock lock];
|
||||
[performers addObject: performer];
|
||||
#if defined(__MINGW__)
|
||||
if (SetEvent(event) == 0)
|
||||
if (INVALID_HANDLE_VALUE != event)
|
||||
{
|
||||
NSLog(@"Set event failed - %@", [NSError _last]);
|
||||
if (SetEvent(event) == 0)
|
||||
{
|
||||
NSLog(@"Set event failed - %@", [NSError _last]);
|
||||
}
|
||||
else
|
||||
{
|
||||
signalled = YES;
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* The write could concievably fail if the pipe is full.
|
||||
|
@ -911,19 +919,30 @@ static void *nsthreadLauncher(void* thread)
|
|||
* and its runloop might stop during that ... so we need to check that
|
||||
* outputFd is still valid.
|
||||
*/
|
||||
while (outputFd >= 0 && write(outputFd, "0", 1) != 1)
|
||||
while (outputFd >= 0
|
||||
&& NO == (signalled = (write(outputFd, "0", 1) == 1) ? YES : NO))
|
||||
{
|
||||
[lock unlock];
|
||||
[lock lock];
|
||||
}
|
||||
#endif
|
||||
if (YES == signalled)
|
||||
{
|
||||
[performers addObject: performer];
|
||||
}
|
||||
[lock unlock];
|
||||
if (NO == signalled)
|
||||
{
|
||||
/* We failed to add the performer ... so we must invalidate it in
|
||||
* case there is code waiting for it to complete.
|
||||
*/
|
||||
[performer invalidate];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[self invalidate];
|
||||
DESTROY(performers);
|
||||
DESTROY(lock);
|
||||
DESTROY(loop);
|
||||
[super dealloc];
|
||||
|
@ -990,9 +1009,11 @@ static void *nsthreadLauncher(void* thread)
|
|||
|
||||
- (void) invalidate
|
||||
{
|
||||
NSArray *p;
|
||||
|
||||
[lock lock];
|
||||
[performers makeObjectsPerformSelector: @selector(invalidate)];
|
||||
[performers removeAllObjects];
|
||||
p = [performers autorelease];
|
||||
performers = nil;
|
||||
#ifdef __MINGW__
|
||||
if (event != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
|
@ -1012,6 +1033,7 @@ static void *nsthreadLauncher(void* thread)
|
|||
}
|
||||
#endif
|
||||
[lock unlock];
|
||||
[p makeObjectsPerformSelector: @selector(invalidate)];
|
||||
}
|
||||
|
||||
- (void) fire
|
||||
|
|
Loading…
Reference in a new issue