Patchwork [4,of,4] tests: killdaemons.py for windows distinguishes access violation and terminated

login
register
mail settings
Submitter Simon Heimberg
Date Feb. 13, 2014, 9:29 p.m.
Message ID <82cd719d21243184d3a0.1392326970@lapsasi>
Download mbox | patch
Permalink /patch/3643/
State Accepted
Commit acbd19b9fbe144ebe7096a3de79897b628993176
Headers show

Comments

Simon Heimberg - Feb. 13, 2014, 9:29 p.m.
# HG changeset patch
# User Simon Heimberg <simohe@besonet.ch>
# Date 1392217758 -3600
#      Wed Feb 12 16:09:18 2014 +0100
# Node ID 82cd719d21243184d3a01a55a92c18c7ae434b23
# Parent  2b97432d8b151b09df176d0b961b276046ecda4d
tests: killdaemons.py for windows distinguishes access violation and terminated

To distinguish between access violaition (process belonging to another user)
and a terminated process, PROCESS_QUERY_INFORMATION must be enabled. But
TerminateProcess still raises error 5 in both cases. Therefore check before if
the process has already terminated.
Matt Mackall - Feb. 13, 2014, 10:27 p.m.
On Thu, 2014-02-13 at 22:29 +0100, Simon Heimberg wrote:
> # HG changeset patch
> # User Simon Heimberg <simohe@besonet.ch>
> # Date 1392217758 -3600
> #      Wed Feb 12 16:09:18 2014 +0100
> # Node ID 82cd719d21243184d3a01a55a92c18c7ae434b23
> # Parent  2b97432d8b151b09df176d0b961b276046ecda4d
> tests: killdaemons.py for windows distinguishes access violation and terminated

These are queued for default, thanks.

Patch

diff -r 2b97432d8b15 -r 82cd719d2124 tests/killdaemons.py
--- a/tests/killdaemons.py	Wed Feb 12 15:38:59 2014 +0100
+++ b/tests/killdaemons.py	Wed Feb 12 16:09:18 2014 +0100
@@ -15,17 +15,24 @@ 
     def kill(pid, logfn, tryhard=True):
         logfn('# Killing daemon process %d' % pid)
         PROCESS_TERMINATE = 1
+        PROCESS_QUERY_INFORMATION = 0x400
         SYNCHRONIZE = 0x00100000L
         WAIT_OBJECT_0 = 0
         WAIT_TIMEOUT = 258
         handle = ctypes.windll.kernel32.OpenProcess(
-                PROCESS_TERMINATE|SYNCHRONIZE, False, pid)
+                PROCESS_TERMINATE|SYNCHRONIZE|PROCESS_QUERY_INFORMATION,
+                False, pid)
         if handle == 0:
             _check(0, 87) # err 87 when process not found
             return # process not found, already finished
         try:
-            _check(ctypes.windll.kernel32.TerminateProcess(handle, -1), 5)
-            #      windows error 5 when process does not exist or no access TODO
+            r = ctypes.windll.kernel32.WaitForSingleObject(handle, 100)
+            if r == WAIT_OBJECT_0:
+                pass # terminated, but process handle still available
+            elif r == WAIT_TIMEOUT:
+                _check(ctypes.windll.kernel32.TerminateProcess(handle, -1))
+            else:
+                _check(r)
 
             # TODO?: forcefully kill when timeout
             #        and ?shorter waiting time? when tryhard==True