Changeset 31703
- Timestamp:
- 2017-05-25T18:47:14+12:00 (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
main/trunk/gli/src/org/greenstone/gatherer/util/SafeProcess.java
r31702 r31703 609 609 610 610 if(mainHandler != null) mainHandler.beforeProcessDestroy(); 611 SafeProcess.destroyProcess(process); // see runProcess(2 args/3 args) 611 boolean noNeedToDestroyIfOnLinux = true; // Interrupt handling suffices to cleanup process and subprocesses on Linux 612 SafeProcess.destroyProcess(process, noNeedToDestroyIfOnLinux); // see runProcess(2 args/3 args) 612 613 if(mainHandler != null) mainHandler.afterProcessDestroy(); 613 614 … … 809 810 // the process and its subprocesses (don't need to call this method at all to terminate the processes: the processes 810 811 // aren't running when we get to this method) 811 log("@@@ Termination signal returned exitvalue 1, on linux this happens when the process has already been terminated");812 log("@@@ Sending termination signal returned exit value 1. On linux this happens when the process has already been terminated"); 812 813 return true; 813 814 } else { … … 820 821 } 821 822 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 } 822 833 823 834 // On linux and mac, p.destroy() suffices to kill processes launched by p as well. 824 835 // On Windows we need to do more work, since otherwise processes launched by p remain around executing until they naturally terminate. 825 836 // e.g. full-import.pl may be terminated with p.destroy(), but it launches import.pl which is left running until it naturally terminates. 826 p ublic static void destroyProcess(Process p) {837 private static void destroyProcess(Process p, boolean canSkipExtraWorkIfLinux) { 827 838 log("### in SafeProcess.destroyProcess(Process p)"); 828 839 829 840 // If it isn't windows, process.destroy() terminates any child processes too 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 831 877 long pid = SafeProcess.getProcessID(p); 832 878 /* … … 845 891 } 846 892 } 847 893 848 894 return; 849 895 } … … 851 897 // else we're on windows: 852 898 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 launched858 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 effect868 } else {869 log("Attempting to terminate sub processes of Windows process with pid " + processID);870 terminateSubProcessesRecursively(processID, p);871 }872 899 873 900 }
Note:
See TracChangeset
for help on using the changeset viewer.