thread fixes

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@31209 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
rfm 2010-08-30 17:27:11 +00:00
parent f5a7ed4073
commit df44085cad
3 changed files with 68 additions and 31 deletions

View file

@ -1,3 +1,10 @@
2010-08-30 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSThread.m: try to make inter-thread notification via
pipe more robust.
* Source/NSTask.m: make windows thread waiting for task into an
NSThread so that any thread-dependent code can work.
2010-08-25 Jonathan Gillaspie <jonathan.gillaspie@testplant.com> 2010-08-25 Jonathan Gillaspie <jonathan.gillaspie@testplant.com>
* Source/Objective2/sync.m: Removed weak declarations * Source/Objective2/sync.m: Removed weak declarations

View file

@ -1010,34 +1010,42 @@ GSPrivateCheckTasks()
static DWORD WINAPI _threadFunction(LPVOID t) static DWORD WINAPI _threadFunction(LPVOID t)
{ {
DWORD milliseconds = 60000; DWORD milliseconds = 60000;
int taskId = [(NSTask*)t processIdentifier]; int taskId;
for (;;)
{
NSConcreteWindowsTask *task; NSConcreteWindowsTask *task;
GSRegisterCurrentThread();
taskId = [(NSTask*)t processIdentifier];
[tasksLock lock]; [tasksLock lock];
task = (NSConcreteWindowsTask*)NSMapGet(activeTasks, task = (NSConcreteWindowsTask*)NSMapGet(activeTasks,
(void*)(intptr_t) taskId); (void*)(intptr_t) taskId);
IF_NO_GC([[task retain] autorelease];) [task retain];
[tasksLock unlock]; [tasksLock unlock];
if (task == nil) if (task != nil)
{ {
return 0; // Task gone away. for (;;)
{
NSConcreteWindowsTask *present;
[tasksLock lock];
present = (NSConcreteWindowsTask*)NSMapGet(activeTasks,
(void*)(intptr_t) taskId);
[tasksLock unlock];
if (present == nil)
{
[task release];
break; // Task gone away.
} }
switch (WaitForSingleObject(task->procInfo.hProcess, milliseconds)) if (WaitForSingleObject(task->procInfo.hProcess, milliseconds)
!= WAIT_TIMEOUT)
{ {
case WAIT_OBJECT_0: [task release];
handleSignal(0); // Signal child process state change. handleSignal(0); // Signal child process state change.
break;
}
}
}
GSUnregisterCurrentThread();
return 0; return 0;
case WAIT_TIMEOUT:
break; // Timeout ... retry
default:
return 0; // Error ... stop watching.
}
}
} }

View file

@ -919,10 +919,11 @@ static void *nsthreadLauncher(void* thread)
NSLog(@"Set event failed - %@", [NSError _last]); NSLog(@"Set event failed - %@", [NSError _last]);
} }
#else #else
if (write(outputFd, "0", 1) != 1) /* The write could concievably fail if the pipe is full, but in that
{ * case we don't care since the other thread should be woken to handle
NSLog(@"Write to pipe failed - %@", [NSError _last]); * reading anyway.
} */
write(outputFd, "0", 1);
#endif #endif
[lock unlock]; [lock unlock];
} }
@ -967,6 +968,20 @@ static void *nsthreadLauncher(void* thread)
[NSException raise: NSInternalInconsistencyException [NSException raise: NSInternalInconsistencyException
format: @"Failed to get non block flag for perform in thread"]; format: @"Failed to get non block flag for perform in thread"];
} }
if ((e = fcntl(outputFd, F_GETFL, 0)) >= 0)
{
e |= NBLK_OPT;
if (fcntl(outputFd, F_SETFL, e) < 0)
{
[NSException raise: NSInternalInconsistencyException
format: @"Failed to set non block flag for perform in thread"];
}
}
else
{
[NSException raise: NSInternalInconsistencyException
format: @"Failed to get non block flag for perform in thread"];
}
} }
else else
{ {
@ -1024,10 +1039,17 @@ static void *nsthreadLauncher(void* thread)
#else #else
if (inputFd >= 0) if (inputFd >= 0)
{ {
if (read(inputFd, &c, 1) != 1) char buf[BUFSIZ];
{
NSLog(@"Read pipe failed - %@", [NSError _last]); /* We don't care how much we read. If there have been multiple
} * performers queued then there will be multiple bytes available,
* but we always handle all available performers, so we can also
* read all available bytes.
* The descriptor is non-blocking ... so it's safe to ask for more
* bytes than are available.
*/
while (read(inputFd, buf, sizeof(buf)) > 0)
;
} }
#endif #endif