This is a refinement of commit
3aa0ac5aa. We still want to hang on
to the mapping between pseudo-process and thread handle, so that we
can still waitpid() after signalling SIGTERM. We just don't want to
wait implicitly on the signalled process anymore.
print $?>>8, "\n";
EXPECT
0
+########
+# Windows fork() emulation: can we still waitpid() after signalling SIGTERM?
+$|=1;
+if (my $pid = fork) {
+ sleep 1;
+ print "1\n";
+ kill 'TERM', $pid;
+ waitpid($pid, 0);
+ print "4\n";
+}
+else {
+ $SIG{TERM} = sub { print "2\n" };
+ sleep 3;
+ print "3\n";
+}
+EXPECT
+1
+2
+3
+4
}
w32_pseudo_child_handles[w32_num_pseudo_children] = handle;
w32_pseudo_child_pids[w32_num_pseudo_children] = id;
+ w32_pseudo_child_sigterm[w32_num_pseudo_children] = 0;
++w32_num_pseudo_children;
# endif
return -(int)id;
(w32_num_pseudo_children-child-1), DWORD);
Move(&w32_pseudo_child_message_hwnds[child+1], &w32_pseudo_child_message_hwnds[child],
(w32_num_pseudo_children-child-1), HWND);
+ Move(&w32_pseudo_child_sigterm[child+1], &w32_pseudo_child_sigterm[child],
+ (w32_num_pseudo_children-child-1), char);
w32_num_pseudo_children--;
}
}
+
+void
+win32_wait_for_children(pTHX)
+{
+ if (w32_pseudo_children && w32_num_pseudo_children) {
+ long child = 0;
+ long count = 0;
+ HANDLE handles[MAXIMUM_WAIT_OBJECTS];
+
+ for (child = 0; child < w32_num_pseudo_children; ++child) {
+ if (!w32_pseudo_child_sigterm[child])
+ handles[count++] = w32_pseudo_child_handles[child];
+ }
+ /* XXX should use MsgWaitForMultipleObjects() to continue
+ * XXX processing messages while we wait.
+ */
+ WaitForMultipleObjects(count, handles, TRUE, INFINITE);
+
+ while (w32_num_pseudo_children)
+ CloseHandle(w32_pseudo_child_handles[--w32_num_pseudo_children]);
+ }
+}
#endif
static int
*/
if (sig == SIGTERM) {
Sleep(0);
- remove_dead_pseudo_process(child);
+ w32_pseudo_child_sigterm[child] = 1;
}
/* It might be us ... */
PERL_ASYNC_CHECK();
DWORD pids[MAXIMUM_WAIT_OBJECTS];
HANDLE handles[MAXIMUM_WAIT_OBJECTS];
HWND message_hwnds[MAXIMUM_WAIT_OBJECTS];
+ char sigterm[MAXIMUM_WAIT_OBJECTS];
} pseudo_child_tab;
#endif
#define w32_pseudo_child_pids (w32_pseudo_children->pids)
#define w32_pseudo_child_handles (w32_pseudo_children->handles)
#define w32_pseudo_child_message_hwnds (w32_pseudo_children->message_hwnds)
+#define w32_pseudo_child_sigterm (w32_pseudo_children->sigterm)
#define w32_internal_host (PL_sys_intern.internal_host)
#define w32_timerid (PL_sys_intern.timerid)
#define w32_message_hwnd (PL_sys_intern.message_hwnd)
#define w32_showwindow (PL_sys_intern.thr_intern.Wshowwindow)
#ifdef USE_ITHREADS
-# define PERL_WAIT_FOR_CHILDREN \
- STMT_START { \
- if (w32_pseudo_children && w32_num_pseudo_children) { \
- long children = w32_num_pseudo_children; \
- WaitForMultipleObjects(children, \
- w32_pseudo_child_handles, \
- TRUE, INFINITE); \
- while (children) \
- CloseHandle(w32_pseudo_child_handles[--children]); \
- } \
- } STMT_END
+void win32_wait_for_children(pTHX);
+# define PERL_WAIT_FOR_CHILDREN win32_wait_for_children(aTHX)
#endif
/* IO.xs and POSIX.xs define PERLIO_NOT_STDIO to 1 */