avid using windows threading api directly

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@31215 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 2010-08-31 10:32:14 +00:00
parent 9adf826758
commit 6b4cc03ada

View file

@ -42,11 +42,11 @@
#import "Foundation/NSNotification.h"
#import "Foundation/NSNotificationQueue.h"
#import "Foundation/NSTask.h"
#import "Foundation/NSThread.h"
#import "Foundation/NSTimer.h"
#import "Foundation/NSLock.h"
#import "GNUstepBase/NSString+GNUstepBase.h"
#import "GNUstepBase/NSObject+GNUstepBase.h"
#import "GNUstepBase/NSThread+GNUstepBase.h"
#import "GSPrivate.h"
#include <string.h>
@ -1005,50 +1005,6 @@ GSPrivateCheckTasks()
TerminateProcess(procInfo.hProcess, 10);
}
/*
* Wait for child process completion.
*/
static DWORD WINAPI _threadFunction(LPVOID t)
{
DWORD milliseconds = 60000;
int taskId;
NSConcreteWindowsTask *task;
GSRegisterCurrentThread();
taskId = [(NSTask*)t processIdentifier];
[tasksLock lock];
task = (NSConcreteWindowsTask*)NSMapGet(activeTasks,
(void*)(intptr_t) taskId);
[task retain];
[tasksLock unlock];
if (task != nil)
{
for (;;)
{
NSConcreteWindowsTask *present;
[tasksLock lock];
present = (NSConcreteWindowsTask*)NSMapGet(activeTasks,
(void*)(intptr_t) taskId);
[tasksLock unlock];
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;
}
static NSString*
endSlashesDoubledFromString(NSString *aString)
@ -1101,9 +1057,53 @@ quotedFromString(NSString *aString)
return resultString;
}
/* Wait for child process completion. The task object is retained by the
* current thread until it exits, but may be removed from the table of
* active tasks by another thread, so we must check that it's still
* active at intervals.
*/
- (void) _windowsTaskWatcher
{
void *taskId = (void*)(intptr_t)[self processIdentifier];
for (;;)
{
NSConcreteWindowsTask *task;
/* Check that this task is still active.
*/
[tasksLock lock];
task = (NSConcreteWindowsTask*)NSMapGet(activeTasks, taskId);
[tasksLock unlock];
if (task != self)
{
/* Task has been reaped by another thread ... so we can exit.
*/
[NSThread exit];
}
/* Wait for up to 1 minute (60,000 milliseconds) to get a notification
* of an event from the subprocess.
*/
if (WaitForSingleObject(procInfo.hProcess, (DWORD)60000)
!= WAIT_TIMEOUT)
{
/* The subprocess has terminated or failed in some way ...
* Set flag so child task can be reaped, then exit since this
* thread no longer needs to watch for events.
*/
handleSignal(0);
[NSThread exit];
}
/* Timed out ... repeat wait attempt.
*/
}
}
- (void) launch
{
DWORD tid;
STARTUPINFOW start_info;
NSString *lpath;
NSString *arg;
@ -1305,10 +1305,13 @@ quotedFromString(NSString *aString)
[tasksLock lock];
NSMapInsert(activeTasks, (void*)(intptr_t) _taskId, (void*)self);
[tasksLock unlock];
/*
* Create thread to watch for termination of process.
*/
wThread = CreateThread(NULL, 0, _threadFunction, (LPVOID)self, 0, &tid);
[NSThread detachNewThreadSelector: @selector(_windowsTaskWatcher)
totarget: self
withObject: nil];
/*
* Close the ends of any pipes used by the child.