wrowe 2003/02/27 11:13:48
Modified: . CHANGES
memory/unix apr_pools.c
threadproc/win32 proc.c signals.c
Log:
As near as I can tell, Win32 will now correspond to Unix in terms of the
availability and lifetime of the hproc process handle.
Revision Changes Path
1.382 +4 -0 apr/CHANGES
Index: CHANGES
===================================================================
RCS file: /home/cvs/apr/CHANGES,v
retrieving revision 1.381
retrieving revision 1.382
diff -u -r1.381 -r1.382
--- CHANGES 24 Feb 2003 23:21:11 -0000 1.381
+++ CHANGES 27 Feb 2003 19:13:48 -0000 1.382
@@ -1,5 +1,9 @@
Changes with APR 0.9.2
+ *) Alter Win32's handling of the apr_proc_t hproc member, so that we
+ close that system handle wherever an apr function would invoke the
+ final waitpid() against a zombie process on Unix. [William Rowe]
+
*) APR_MAX_SECONDS_TO_LINGER
and APR_FNM_* #defines replace their
old undecorated names (missing APR_ prefix). The old names will
disappear with APR 1.0.0.
1.194 +6 -21 apr/memory/unix/apr_pools.c
Index: apr_pools.c
===================================================================
RCS file: /home/cvs/apr/memory/unix/apr_pools.c,v
retrieving revision 1.193
retrieving revision 1.194
diff -u -r1.193 -r1.194
--- apr_pools.c 27 Feb 2003 18:54:04 -0000 1.193
+++ apr_pools.c 27 Feb 2003 19:13:48 -0000 1.194
@@ -2066,6 +2066,7 @@
#endif /* !defined(NEED_WAITPID) */
for (pc = procs; pc; pc = pc->next) {
+#ifndef WIN32
if ((pc->kill_how == APR_KILL_AFTER_TIMEOUT)
|| (pc->kill_how == APR_KILL_ONLY_ONCE)) {
/*
@@ -2074,14 +2075,15 @@
* similar to a SIGKILL, so always give the process a timeout
* under Windows before killing it.
*/
-#ifdef WIN32
- need_timeout = 1;
-#else /* !defined(WIN32) */
if (apr_proc_kill(pc->proc, SIGTERM) == APR_SUCCESS)
need_timeout = 1;
-#endif /* !defined(WIN32) */
}
else if (pc->kill_how == APR_KILL_ALWAYS) {
+#else /* WIN32 knows only one fast, clean method of killing processes today
*/
+ if (pc->kill_how != APR_KILL_NEVER) {
+ need_timeout = 1;
+ pc->kill_how = APR_KILL_ALWAYS;
+#endif
apr_proc_kill(pc->proc, SIGKILL);
}
}
@@ -2130,23 +2132,6 @@
if (pc->kill_how != APR_KILL_NEVER)
(void)apr_proc_wait(pc->proc, NULL, NULL, APR_WAIT);
}
-
-#ifdef WIN32
- /*
- * XXX: Do we need an APR function to clean-up a proc_t?
- * Well ... yeah ... but we can't since it's scope is ill defined.
- * We can't dismiss the handle until the apr_proc_wait above is
- * finished with the proc_t.
- */
- {
- for (pc = procs; pc; pc = pc->next) {
- if (pc->proc->hproc) {
- CloseHandle(pc->proc->hproc);
- pc->proc->hproc = NULL;
- }
- }
- }
-#endif /* defined(WIN32) */
}
1.90 +6 -1 apr/threadproc/win32/proc.c
Index: proc.c
===================================================================
RCS file: /home/cvs/apr/threadproc/win32/proc.c,v
retrieving revision 1.89
retrieving revision 1.90
diff -u -r1.89 -r1.90
--- proc.c 24 Feb 2003 23:27:14 -0000 1.89
+++ proc.c 27 Feb 2003 19:13:48 -0000 1.90
@@ -699,7 +699,10 @@
apr_pool_t *p)
{
/* Unix does apr_proc_wait(proc(-1), exitcode, exitwhy, waithow)
- * but Win32's apr_proc_wait won't work that way.
+ * but Win32's apr_proc_wait won't work that way. We can either
+ * register all APR created processes in some sort of AsyncWait
+ * thread, or simply walk from the global process pool for all
+ * apr_pool_note_subprocess()es registered with APR.
*/
return APR_ENOTIMPL;
}
@@ -735,6 +738,8 @@
*exitcode = stat;
if (exitwhy)
*exitwhy = why_from_exit_code(stat);
+ CloseHandle(proc->hproc);
+ proc->hproc = NULL;
return APR_CHILD_DONE;
}
}
1.25 +9 -3 apr/threadproc/win32/signals.c
Index: signals.c
===================================================================
RCS file: /home/cvs/apr/threadproc/win32/signals.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -r1.24 -r1.25
--- signals.c 25 Feb 2003 13:55:56 -0000 1.24
+++ signals.c 27 Feb 2003 19:13:48 -0000 1.25
@@ -65,15 +65,20 @@
#include <sys/wait.h>
#endif
-/* Windows only really support killing process, but that will do for now. */
+/* Windows only really support killing process, but that will do for now.
+ *
+ * ### Actually, closing the input handle to the proc should also do fine
+ * for most console apps. This definately needs improvement...
+ */
APR_DECLARE(apr_status_t) apr_proc_kill(apr_proc_t *proc, int signal)
{
if (proc->hproc != NULL) {
if (TerminateProcess(proc->hproc, signal) == 0) {
return apr_get_os_error();
}
- CloseHandle(proc->hproc);
- proc->hproc = NULL;
+ /* On unix, SIGKILL leaves a apr_proc_wait()able pid lying around,
+ * so we will leave hproc alone until the app calls apr_proc_wait().
+ */
return APR_SUCCESS;
}
return APR_EPROC_UNKNOWN;
@@ -82,6 +87,7 @@
void apr_signal_init(apr_pool_t *pglobal)
{
}
+
const char *apr_signal_description_get(int signum)
{
return "unknown signal (not supported)";