mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-28 03:00:51 +00:00
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:
parent
f5a7ed4073
commit
df44085cad
3 changed files with 68 additions and 31 deletions
|
@ -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
|
||||||
|
|
|
@ -1009,35 +1009,43 @@ 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;
|
||||||
|
NSConcreteWindowsTask *task;
|
||||||
|
|
||||||
for (;;)
|
GSRegisterCurrentThread();
|
||||||
|
taskId = [(NSTask*)t processIdentifier];
|
||||||
|
[tasksLock lock];
|
||||||
|
task = (NSConcreteWindowsTask*)NSMapGet(activeTasks,
|
||||||
|
(void*)(intptr_t) taskId);
|
||||||
|
[task retain];
|
||||||
|
[tasksLock unlock];
|
||||||
|
if (task != nil)
|
||||||
{
|
{
|
||||||
NSConcreteWindowsTask *task;
|
for (;;)
|
||||||
|
|
||||||
[tasksLock lock];
|
|
||||||
task = (NSConcreteWindowsTask*)NSMapGet(activeTasks,
|
|
||||||
(void*)(intptr_t) taskId);
|
|
||||||
IF_NO_GC([[task retain] autorelease];)
|
|
||||||
[tasksLock unlock];
|
|
||||||
if (task == nil)
|
|
||||||
{
|
{
|
||||||
return 0; // Task gone away.
|
NSConcreteWindowsTask *present;
|
||||||
}
|
|
||||||
switch (WaitForSingleObject(task->procInfo.hProcess, milliseconds))
|
|
||||||
{
|
|
||||||
case WAIT_OBJECT_0:
|
|
||||||
handleSignal(0); // Signal child process state change.
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case WAIT_TIMEOUT:
|
[tasksLock lock];
|
||||||
break; // Timeout ... retry
|
present = (NSConcreteWindowsTask*)NSMapGet(activeTasks,
|
||||||
|
(void*)(intptr_t) taskId);
|
||||||
default:
|
[tasksLock unlock];
|
||||||
return 0; // Error ... stop watching.
|
if (present == nil)
|
||||||
|
{
|
||||||
|
[task release];
|
||||||
|
break; // Task gone away.
|
||||||
|
}
|
||||||
|
if (WaitForSingleObject(task->procInfo.hProcess, milliseconds)
|
||||||
|
!= WAIT_TIMEOUT)
|
||||||
|
{
|
||||||
|
[task release];
|
||||||
|
handleSignal(0); // Signal child process state change.
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
GSUnregisterCurrentThread();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue