diff --git a/Main.cs b/Main.cs index 9ca2884..f2d894a 100644 --- a/Main.cs +++ b/Main.cs @@ -337,32 +337,24 @@ namespace winsw StopProcessAndChildren(Convert.ToInt32(mo["ProcessID"])); } - try + var proc = Process.GetProcessById(pid); + WriteEvent("Send SIGINT " + process.Id); + bool successful = SigIntHelper.SendSIGINTToProcess(proc,descriptor.StopTimeout); + if (successful) { - var proc = Process.GetProcessById(pid); - if (descriptor.SendSIGINT) + WriteEvent("SIGINT to" + process.Id + " successful"); + } + else + { + try { - WriteEvent("Send SIGINT " + process.Id); - bool successful = SigIntHelper.SendSIGINTToProcess(proc); - if (successful) - { - WriteEvent("SIGINT to" + process.Id + " successful"); - } - else - { - WriteEvent("SIGINT to " + process.Id + " failed - Killing as fallback"); - proc.Kill(); - } - } - else - { - WriteEvent("ProcessKill " + process.Id); + WriteEvent("SIGINT to " + process.Id + " failed - Killing as fallback"); proc.Kill(); } - } - catch (ArgumentException) - { - // Process already exited. + catch (ArgumentException) + { + // Process already exited. + } } } diff --git a/README.markdown b/README.markdown index b1d3b3a..19a6610 100644 --- a/README.markdown +++ b/README.markdown @@ -185,6 +185,13 @@ When you use the ``, you must use `` instead of `catalina.sh stop +### stoptimeout +When the service is requested to stop, winsw first attempts to send Ctrl+C signal to the process, then wait for up to 15 seconds for the process to exit by itself gracefully. A process failing to do that (or if the process does not have a console), then winsw resorts to calling TerminateProcess API to kill the service instantly. + +This optional element allows you to change this "15 seconds" value, so that you can control how long winsw gives the service to shut itself down. See `` below for how to specify time duration: + + 10sec + ### env This optional element can be specified multiple times if necessary to specify environment variables to be set for the child process. The syntax is: @@ -253,4 +260,4 @@ It is possible to specify the useraccount (and password) that the service will r ### Working directory Some services need to run with a working directory specified. To do this, specify a `` element like this: - C:\application \ No newline at end of file + C:\application diff --git a/ServiceDescriptor.cs b/ServiceDescriptor.cs index 937cb54..92b99a4 100755 --- a/ServiceDescriptor.cs +++ b/ServiceDescriptor.cs @@ -562,14 +562,14 @@ namespace winsw } /// - /// True if the service can interact with the desktop. + /// Time to wait for the service to gracefully shutdown before we forcibly kill it /// - public bool SendSIGINT - { - get - { - return dom.SelectSingleNode("//sendsigint") != null; - } - } + public TimeSpan StopTimeout + { + get + { + return SingleTimeSpanElement(dom, "stoptimeout", TimeSpan.FromSeconds(15)); + } + } } } diff --git a/SigIntHelper.cs b/SigIntHelper.cs index 3378d09..13a7db4 100644 --- a/SigIntHelper.cs +++ b/SigIntHelper.cs @@ -41,7 +41,7 @@ namespace winsw /// /// The process to attach to and send the SIGINT /// True if the process shut down successfully to the SIGINT, false if it did not. - public static bool SendSIGINTToProcess(Process process) + public static bool SendSIGINTToProcess(Process process, TimeSpan shutdownTimeout) { if (AttachConsole((uint)process.Id)) { @@ -49,7 +49,7 @@ namespace winsw SetConsoleCtrlHandler(null, true); GenerateConsoleCtrlEvent(CtrlTypes.CTRL_C_EVENT, 0); - process.WaitForExit(15000); + process.WaitForExit(shutdownTimeout.TotalMilliseconds); return process.HasExited; } @@ -59,4 +59,4 @@ namespace winsw } } } -} \ No newline at end of file +}