summaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
authorRocco Caputo <troc@netrus.net>2001-12-09 13:12:38 -0500
committerJarkko Hietaniemi <jhi@iki.fi>2001-12-10 00:04:56 +0000
commit932b74874cde09c18c99efef628e815e5bd4bf76 (patch)
tree2277f510c28060b8472effb7605b00061bff9c53 /win32
parent304b2fa907abeb9c21f4411c980ea090225121a3 (diff)
downloadperl-932b74874cde09c18c99efef628e815e5bd4bf76.tar.gz
[patch] non-blocking waitpid(-1,WNOHANG) for MSWin32
Message-ID: <20011209181238.A803@eyrie.homenet> p4raw-id: //depot/perl@13575
Diffstat (limited to 'win32')
-rw-r--r--win32/win32.c129
1 files changed, 72 insertions, 57 deletions
diff --git a/win32/win32.c b/win32/win32.c
index 2877da8157..bad03490e8 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -1690,6 +1690,76 @@ win32_uname(struct utsname *name)
return 0;
}
+int
+win32_internal_wait(int *status, DWORD timeout)
+{
+ /* XXX this wait emulation only knows about processes
+ * spawned via win32_spawnvp(P_NOWAIT, ...).
+ */
+ dTHX;
+ int i, retval;
+ DWORD exitcode, waitcode;
+
+#ifdef USE_ITHREADS
+ if (w32_num_pseudo_children) {
+ waitcode = WaitForMultipleObjects(w32_num_pseudo_children,
+ w32_pseudo_child_handles,
+ FALSE,
+ timeout);
+ /* Time out here if there are no other children to wait for. */
+ if (waitcode == WAIT_TIMEOUT) {
+ if (!w32_num_children) {
+ return 0;
+ }
+ }
+ else if (waitcode != WAIT_FAILED) {
+ if (waitcode >= WAIT_ABANDONED_0
+ && waitcode < WAIT_ABANDONED_0 + w32_num_pseudo_children)
+ i = waitcode - WAIT_ABANDONED_0;
+ else
+ i = waitcode - WAIT_OBJECT_0;
+ if (GetExitCodeThread(w32_pseudo_child_handles[i], &exitcode)) {
+ *status = (int)((exitcode & 0xff) << 8);
+ retval = (int)w32_pseudo_child_pids[i];
+ remove_dead_pseudo_process(i);
+ return -retval;
+ }
+ }
+ }
+#endif
+
+ if (!w32_num_children) {
+ errno = ECHILD;
+ return -1;
+ }
+
+ /* if a child exists, wait for it to die */
+ waitcode = WaitForMultipleObjects(w32_num_children,
+ w32_child_handles,
+ FALSE,
+ timeout);
+ if (waitcode == WAIT_TIMEOUT) {
+ return 0;
+ }
+ if (waitcode != WAIT_FAILED) {
+ if (waitcode >= WAIT_ABANDONED_0
+ && waitcode < WAIT_ABANDONED_0 + w32_num_children)
+ i = waitcode - WAIT_ABANDONED_0;
+ else
+ i = waitcode - WAIT_OBJECT_0;
+ if (GetExitCodeProcess(w32_child_handles[i], &exitcode) ) {
+ *status = (int)((exitcode & 0xff) << 8);
+ retval = (int)w32_child_pids[i];
+ remove_dead_process(i);
+ return retval;
+ }
+ }
+
+FAILED:
+ errno = GetLastError();
+ return -1;
+}
+
DllExport int
win32_waitpid(int pid, int *status, int flags)
{
@@ -1698,7 +1768,7 @@ win32_waitpid(int pid, int *status, int flags)
int retval = -1;
long child;
if (pid == -1) /* XXX threadid == 1 ? */
- return win32_wait(status);
+ return win32_internal_wait(status, timeout);
#ifdef USE_ITHREADS
else if (pid < 0) {
child = find_pseudo_pid(-pid);
@@ -1774,62 +1844,7 @@ alien_process:
DllExport int
win32_wait(int *status)
{
- /* XXX this wait emulation only knows about processes
- * spawned via win32_spawnvp(P_NOWAIT, ...).
- */
- dTHX;
- int i, retval;
- DWORD exitcode, waitcode;
-
-#ifdef USE_ITHREADS
- if (w32_num_pseudo_children) {
- waitcode = WaitForMultipleObjects(w32_num_pseudo_children,
- w32_pseudo_child_handles,
- FALSE,
- INFINITE);
- if (waitcode != WAIT_FAILED) {
- if (waitcode >= WAIT_ABANDONED_0
- && waitcode < WAIT_ABANDONED_0 + w32_num_pseudo_children)
- i = waitcode - WAIT_ABANDONED_0;
- else
- i = waitcode - WAIT_OBJECT_0;
- if (GetExitCodeThread(w32_pseudo_child_handles[i], &exitcode)) {
- *status = (int)((exitcode & 0xff) << 8);
- retval = (int)w32_pseudo_child_pids[i];
- remove_dead_pseudo_process(i);
- return -retval;
- }
- }
- }
-#endif
-
- if (!w32_num_children) {
- errno = ECHILD;
- return -1;
- }
-
- /* if a child exists, wait for it to die */
- waitcode = WaitForMultipleObjects(w32_num_children,
- w32_child_handles,
- FALSE,
- INFINITE);
- if (waitcode != WAIT_FAILED) {
- if (waitcode >= WAIT_ABANDONED_0
- && waitcode < WAIT_ABANDONED_0 + w32_num_children)
- i = waitcode - WAIT_ABANDONED_0;
- else
- i = waitcode - WAIT_OBJECT_0;
- if (GetExitCodeProcess(w32_child_handles[i], &exitcode) ) {
- *status = (int)((exitcode & 0xff) << 8);
- retval = (int)w32_child_pids[i];
- remove_dead_process(i);
- return retval;
- }
- }
-
-FAILED:
- errno = GetLastError();
- return -1;
+ return win32_internal_wait(status, INFINITE);
}
#ifndef PERL_IMPLICIT_CONTEXT