executor.java
来自「opennms得相关源码 请大家看看」· Java 代码 · 共 614 行 · 第 1/2 页
JAVA
614 行
//// This file is part of the OpenNMS(R) Application.//// OpenNMS(R) is Copyright (C) 2002-2003 The OpenNMS Group, Inc. All rights reserved.// OpenNMS(R) is a derivative work, containing both original code, included code and modified// code that was published under the GNU General Public License. Copyrights for modified // and included code are below.//// OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc.//// Modifications://// 2003 Jan 31: Cleaned up some unused imports.//// Original code base Copyright (C) 1999-2001 Oculan Corp. All rights reserved.//// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.//// For more information contact:// OpenNMS Licensing <license@opennms.org>// http://www.opennms.org/// http://www.opennms.com///// Tab Size = 8//package org.opennms.netmgt.actiond;import java.io.IOException;import java.util.ArrayList;import java.util.Collections;import java.util.Iterator;import java.util.LinkedList;import java.util.List;import org.apache.log4j.Category;import org.opennms.core.fiber.PausableFiber;import org.opennms.core.queue.FifoQueue;import org.opennms.core.queue.FifoQueueException;import org.opennms.core.utils.ThreadCategory;/** * This class is used as a thread for launching and executing actions as they * are discovered by the action daemon. The actions are read from an execution * queue and the processes are created by the fiber. Each created process is * added to garbage collection list that is periodically polled and culled based * upon the status of the process or how long the process is run. If the process * has run long than allocated it is terminated during collection. * * @author <a href="mailto:mike@opennms.org">Mike Davidson </a> * @author <a href="mailto:weave@oculan.com">Brian Weaver </a> * @author <a href="http://www.opennms.org/>OpenNMS </a> * */final class Executor implements Runnable, PausableFiber { /** * The input queue of runnable commands. */ private FifoQueue m_execQ; /** * The list of outstanding commands. */ private List m_processes; /** * The maximum time that a command can execute. */ private long m_maxWait; /** * The maximum number of outstanding processes. */ private int m_maxProcCount; /** * The process garbage collection thread. */ private Thread m_reaper; /** * The garbage collection instance. */ private Runnable m_reaperRun; /** * The worker thread that executes the <code>run</code> method. */ private Thread m_worker; /** * The name of this Fiber */ private String m_name; /** * The status of this fiber. */ private int m_status; /** * This class is designed to encapsulated a process and its start time. The * start time is based upon the system clock and the runtime is the * difference between the current time and the started time. * * @author <a href="mailto:mike@opennms.org">Mike Davidson </a> * @author <a href="mailto:weave@oculan.com">Brian Weaver </a> * @author <a href="http://www.opennms.org/>OpenNMS </a> * */ private static final class DatedProc { /** * The executable running */ private final String m_cmd; /** * The process returned from the {@link java.lang.Runtime Runtime} * instance. */ private final Process m_proc; /** * The time the process was started. */ private final long m_started; /** * Constructs a new dated process. * * @param cmd * The command used to start the process. * @param p * The running process. */ DatedProc(String cmd, Process p) { m_cmd = cmd; m_proc = p; m_started = System.currentTimeMillis(); } /** * Returns the encapsulated process. * */ Process getProcess() { return m_proc; } /** * Returns the current runtime of the process. */ long getRunTime() { return System.currentTimeMillis() - m_started; } /** * Returns the command being run by the dated process. */ public String toString() { return m_cmd; } } // end class DatedProc /** * This class encapsules a singular run method that is used to * <em>garbage collect</em> expired processes. If a process has exceeded * its maximum runtime then it is killed and removed from the process queue. * * @author <a href="mailto:mike@opennms.org">Mike Davidson </a> * @author <a href="mailto:weave@oculan.com">Brian Weaver </a> * @author <a href="http://www.opennms.org/>OpenNMS </a> * */ private final class Reaper implements Runnable { /** * The reaper execution enviroment. This method scans the process array * and removes expired and completed commands from the array on a * periodic basis. In that respect it is a garbage collection thread for * processes. * */ public void run() { // Wait for a maximum of 15 seconds between checks! // long waitPeriod = m_maxWait / 5; if (waitPeriod > 15000) { waitPeriod = 15000; } Category log = ThreadCategory.getInstance(Executor.class); // Begin the checking process. // // Make sure to leave the 'this' keyword associated with the // getClass() call or jikes will complain. The 'this' keyword // removes all ambiguity in the call. // for (;;) { // run and check the queue once about // 1/5 of the maximum run time. // synchronized (m_processes) { Iterator i = m_processes.iterator(); while (i.hasNext()) { DatedProc dp = (DatedProc) i.next(); try { int rc = dp.getProcess().exitValue(); if (log.isDebugEnabled()) { log.debug("Process " + dp + " completed, rc = " + rc); } i.remove(); continue; } catch (IllegalThreadStateException ex) { } // still running if (dp.getRunTime() > m_maxWait) { if (log.isInfoEnabled()) log.info("Process " + dp + " did not complete in the alloted time, terminating."); dp.getProcess().destroy(); i.remove(); } } } synchronized (this) { // the 'this' keyword should not be removed // or else jikes will complain about an ambiguous // call. this.notifyAll(); // sleep for 1/5 of wait time or // 15 seconds, which ever is smaller. // try { // the 'this' keyword should not be removed // or else jikes will complain about an ambiguous // call. this.wait(waitPeriod); } catch (InterruptedException ex) { // this is used as a shutdown mechinism break; } } } // end for(;;) } // end run } // end class Reaper /** * <p> * Converts a single command to an array that can be passed to the * {@link java.lang.Runtime#exec(java.lang.String[]) exec}system call. The * element at index zero of the array is the name of the executable to run. * Indexs [1..length) are the arguments passed to the executable command. * </p> * * <p> * The input command has is white space trimmed before processing. The basic * processing is to split on spaces, except when a double quote or single * quote is encountered. Also backspaces(\) should also be handled correctly * both in and out of the quotes. Shell escapes with <em>$</em> are not * supported. * </p> * * @param cmd * The command to split into an array. * * @return The execution array. * */ private static String[] getExecArguments(String cmd) { Category log = ThreadCategory.getInstance(Executor.class); // make sure we get rid of excess white space. // cmd = cmd.trim(); // get the processing elements. // StringBuffer buf = new StringBuffer(); List args = new ArrayList(5); char[] chars = cmd.toCharArray(); boolean dquoted = false; boolean squoted = false; for (int x = 0; x < chars.length; x++) { if (chars[x] == '\\') { if (squoted) { buf.append(chars[x]).append(chars[x + 1]);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?