mirror of
https://github.com/gnustep/libs-base.git
synced 2025-06-02 01:21:08 +00:00
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:
parent
8b70f7ec9d
commit
58e55d4215
1 changed files with 50 additions and 47 deletions
|
@ -42,11 +42,11 @@
|
||||||
#import "Foundation/NSNotification.h"
|
#import "Foundation/NSNotification.h"
|
||||||
#import "Foundation/NSNotificationQueue.h"
|
#import "Foundation/NSNotificationQueue.h"
|
||||||
#import "Foundation/NSTask.h"
|
#import "Foundation/NSTask.h"
|
||||||
|
#import "Foundation/NSThread.h"
|
||||||
#import "Foundation/NSTimer.h"
|
#import "Foundation/NSTimer.h"
|
||||||
#import "Foundation/NSLock.h"
|
#import "Foundation/NSLock.h"
|
||||||
#import "GNUstepBase/NSString+GNUstepBase.h"
|
#import "GNUstepBase/NSString+GNUstepBase.h"
|
||||||
#import "GNUstepBase/NSObject+GNUstepBase.h"
|
#import "GNUstepBase/NSObject+GNUstepBase.h"
|
||||||
#import "GNUstepBase/NSThread+GNUstepBase.h"
|
|
||||||
#import "GSPrivate.h"
|
#import "GSPrivate.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -1005,50 +1005,6 @@ GSPrivateCheckTasks()
|
||||||
TerminateProcess(procInfo.hProcess, 10);
|
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*
|
static NSString*
|
||||||
endSlashesDoubledFromString(NSString *aString)
|
endSlashesDoubledFromString(NSString *aString)
|
||||||
|
@ -1101,9 +1057,53 @@ quotedFromString(NSString *aString)
|
||||||
return resultString;
|
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
|
- (void) launch
|
||||||
{
|
{
|
||||||
DWORD tid;
|
|
||||||
STARTUPINFOW start_info;
|
STARTUPINFOW start_info;
|
||||||
NSString *lpath;
|
NSString *lpath;
|
||||||
NSString *arg;
|
NSString *arg;
|
||||||
|
@ -1305,10 +1305,13 @@ quotedFromString(NSString *aString)
|
||||||
[tasksLock lock];
|
[tasksLock lock];
|
||||||
NSMapInsert(activeTasks, (void*)(intptr_t) _taskId, (void*)self);
|
NSMapInsert(activeTasks, (void*)(intptr_t) _taskId, (void*)self);
|
||||||
[tasksLock unlock];
|
[tasksLock unlock];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create thread to watch for termination of process.
|
* 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.
|
* Close the ends of any pipes used by the child.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue