| 823 | public static void destroyProcess(Process p) { |
| 824 | // A cancel action results in an interruption to the process thread, which in turn interrupts |
| 825 | // the SafeProcess' worker threads, all which clean up after themselves. |
| 826 | // On linux, this suffices to cleanly terminate a Process and any subprocesses that may have launched |
| 827 | // so we don't need to do extra work in such a case. But the interrupts happen only when SafeProcess calls |
| 828 | // destroyProcess() on the Process it was running internally, and not if anyone else tries to end a |
| 829 | // Process by calling SafeProcess.destroyProcess(p). In such cases, the Process needs to be actively terminated: |
| 830 | boolean canSkipExtraWorkIfLinux = true; |
| 831 | SafeProcess.destroyProcess(p, !canSkipExtraWorkIfLinux); |
| 832 | } |
830 | | if(!Utility.isWindows()) { |
| 841 | if(Utility.isWindows()) { |
| 842 | |
| 843 | if(!SafeProcess.isAvailable("wmic")) { |
| 844 | log("wmic, used to kill subprocesses, is not available. Unable to terminate subprocesses..."); |
| 845 | log("Kill them manually from the TaskManager or they will proceed to run to termination"); |
| 846 | |
| 847 | // At least we can get rid of the top level process we launched |
| 848 | p.destroy(); |
| 849 | return; |
| 850 | } |
| 851 | |
| 852 | // get the process id of the process we launched, |
| 853 | // so we can use it to find the pids of any subprocesses it launched in order to terminate those too. |
| 854 | |
| 855 | long processID = SafeProcess.getProcessID(p); |
| 856 | if(processID == -1) { // the process doesn't exist or no longer exists (terminated naturally?) |
| 857 | p.destroy(); // minimum step, do this anyway, at worst there's no process and this won't have any effect |
| 858 | } else { |
| 859 | log("Attempting to terminate sub processes of Windows process with pid " + processID); |
| 860 | terminateSubProcessesRecursively(processID, p); |
| 861 | } |
| 862 | return; |
| 863 | |
| 864 | } |
| 865 | else { // linux or mac |
| 866 | |
| 867 | // if we're on linux and would have already terminated by now (in which case canSkipExtraWorkForLinux would be true), |
| 868 | // then there's nothing much left to do. This would only be the case if SafeProcess is calling this method on its |
| 869 | // internal process, since it would have successfully cleaned up on Interruption and there would be no process left running |
| 870 | if(!Utility.isMac() && canSkipExtraWorkIfLinux) { |
| 871 | log("@@@ Linux: Cancelling a SafeProcess instance does not require any complicated system destroy operation"); |
| 872 | p.destroy(); // vestigial: this will have no effect if the process had already terminated, which is the case in this block |
| 873 | return; |
| 874 | } |
| 875 | // else we're on a Mac or an external caller (not SafeProcess) has requested explicit termination on Linux |
| 876 | |
853 | | if(!SafeProcess.isAvailable("wmic")) { |
854 | | log("wmic, used to kill subprocesses, is not available. Unable to terminate subprocesses..."); |
855 | | log("Kill them manually from the TaskManager or they will proceed to run to termination"); |
856 | | |
857 | | // At least we can get rid of the top level process we launched |
858 | | p.destroy(); |
859 | | return; |
860 | | } |
861 | | |
862 | | // get the process id of the process we launched, |
863 | | // so we can use it to find the pids of any subprocesses it launched in order to terminate those too. |
864 | | |
865 | | long processID = SafeProcess.getProcessID(p); |
866 | | if(processID == -1) { // the process doesn't exist or no longer exists (terminated naturally?) |
867 | | p.destroy(); // minimum step, do this anyway, at worst there's no process and this won't have any effect |
868 | | } else { |
869 | | log("Attempting to terminate sub processes of Windows process with pid " + processID); |
870 | | terminateSubProcessesRecursively(processID, p); |
871 | | } |