[PATCH 1 of 2] run-tests: implement proper process killing for Windows

Mads Kiilerich mads at kiilerich.com
Sun Jun 17 19:20:50 CDT 2012


Adrian Buehlmann wrote, On 06/18/2012 12:35 AM:
> # HG changeset patch
> # User Adrian Buehlmann <adrian at cadifra.com>
> # Date 1339972395 -7200
> # Node ID 954a063d12edfe1d2a3d32df1a540c0ee5268156
> # Parent  191f0c6cc47c1cf85372f5e5943ca94aa14fcb65
> run-tests: implement proper process killing for Windows

This is allegedly a hard problem. It is great to have it solved!

> diff --git a/tests/run-tests.py b/tests/run-tests.py
> --- a/tests/run-tests.py
> +++ b/tests/run-tests.py
> @@ -347,6 +347,25 @@
>       except OSError:
>           pass
>   
> +if os.name == 'nt':
> +    import ctypes
> +    def killprocess(pid):
> +        vlog('# Killing daemon process %d' % pid)
> +        PROCESS_TERMINATE = 1
> +        k = ctypes.windll.kernel32
> +        handle = k.OpenProcess(PROCESS_TERMINATE, False, pid)
> +        k.TerminateProcess(handle, -1)
> +        k.CloseHandle(handle)

How is this different from os.kill ... or msys kill? Why can't os.kill 
be used? I assume you have done some research and found something that 
would be helpful to have in the commit message for the next guy looking 
at this.

The non-windows variant try to make the process terminate cleanly before 
kill-killing it. Is that relevant and possible on Windows too?

> +else:
> +    def killprocess(pid):
> +        os.kill(pid, 0)
> +        vlog('# Killing daemon process %d' % pid)
> +        os.kill(pid, signal.SIGTERM)
> +        time.sleep(0.1)
> +        os.kill(pid, 0)
> +        vlog('# Daemon process %d is stuck - really killing it' % pid)
> +        os.kill(pid, signal.SIGKILL)
> +
>   def killdaemons():
>       # Kill off any leftover daemon processes
>       try:
> @@ -357,13 +376,7 @@
>               except ValueError:
>                   continue
>               try:
> -                os.kill(pid, 0)
> -                vlog('# Killing daemon process %d' % pid)
> -                os.kill(pid, signal.SIGTERM)
> -                time.sleep(0.1)
> -                os.kill(pid, 0)
> -                vlog('# Daemon process %d is stuck - really killing it' % pid)
> -                os.kill(pid, signal.SIGKILL)
> +                killprocess(pid)
>               except OSError, err:
>                   if err.errno != errno.ESRCH:
>                       raise

Will the Windows implementation also throw OSError with ESRCH ... or is 
it specific for the non-Windows implementation?

/Mads



More information about the Mercurial-devel mailing list