You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by do...@apache.org on 2001/12/23 05:53:27 UTC
cvs commit: jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/framework/exec ProcessMonitor.java
donaldp 01/12/22 20:53:27
Added: proposal/myrmidon/src/java/org/apache/myrmidon/framework/exec
ProcessMonitor.java
Log:
Add in class that will replace ExecuteWatchDog, ExeuteStreamHandler and related classes.
Revision Changes Path
1.1 jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/framework/exec/ProcessMonitor.java
Index: ProcessMonitor.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.myrmidon.framework.exec;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
/**
* This class is responsible for monitoring a process.
* It will monitor a process and if it goes longer than its timeout
* then it will terminate it. The monitor will also read data from
* stdout and stderr of process and pass it onto user specified streams.
* It will also in the future do the same for stdin.
*
* @author <a href="mailto:peter@apache.org">Peter Donald</a>
* @version $Revision: 1.1 $ $Date: 2001/12/23 04:53:27 $
*/
public class ProcessMonitor
extends AbstractLogEnabled
implements Runnable
{
//Time to sleep in loop while processing output
//of command and monitoring for timeout
private final static int SLEEP_TIME = 5;
//State to indicate process is still running
private static final int STATE_RUNNING = 0;
//State to indicate process shutdown by itself
private static final int STATE_STOPPED = 1;
//State to indicate process was terminated due to timeout
private static final int STATE_TERMINATED = 2;
/**
* The state of the process monitor and thus
* the state of the underlying process.
*/
private int m_state = STATE_RUNNING;
/**
* This is the process we are monitoring.
*/
private final Process m_process;
/**
* This specifies the time at which this process will
* timeout. 0 implies no timeout.
*/
private final long m_timeout;
/**
* Stream from which to read standard input.
*/
private final InputStream m_input;
/**
* Stream to write standard output to.
*/
private final OutputStream m_output;
/**
* Stream to write standard error to.
*/
private final OutputStream m_error;
public ProcessMonitor( final Process process,
final InputStream input,
final OutputStream output,
final OutputStream error,
final long timeoutDuration )
{
if( null == process )
{
throw new NullPointerException( "process" );
}
if( 0 > timeoutDuration )
{
throw new IllegalArgumentException( "timeoutDuration" );
}
final long now = System.currentTimeMillis();
long timeout = 0;
if( 0 != timeoutDuration )
{
timeout = now + timeoutDuration;
}
m_process = process;
m_input = input;
m_output = output;
m_error = error;
m_timeout = timeout;
}
/**
* Thread method to monitor the state of the process.
*/
public void run()
{
while( STATE_RUNNING == m_state )
{
processStandardInput();
processStandardOutput();
processStandardError();
if( !isProcessStopped() )
{
checkTimeout();
}
try
{
Thread.sleep( SLEEP_TIME );
}
catch( final InterruptedException ie )
{
//swallow it
}
}
}
/**
* Check if process has stopped. If it has then update state
* and return true, else return false.
*/
private boolean isProcessStopped()
{
boolean stopped;
try
{
m_process.exitValue();
stopped = true;
}
catch( final IllegalThreadStateException itse )
{
stopped = false;
}
if( stopped )
{
m_state = STATE_STOPPED;
}
return stopped;
}
/**
* Check if the process has exceeded time allocated to it.
* If it has reached timeout then terminate the process
* and set state to <code>STATE_TERMINATED</code>.
*/
private void checkTimeout()
{
if( 0 == m_timeout )
{
return;
}
final long now = System.currentTimeMillis();
if( now > m_timeout )
{
m_state = STATE_TERMINATED;
m_process.destroy();
}
}
/**
* Process the standard input of process.
* Reading it from user specified stream and copy it
* to processes standard input stream.
*/
private void processStandardInput()
{
if( null != m_input )
{
//Note can not do this as the process may block
//when written to which will result in this whole
//thread being blocked. Probably need to write to
//stdin in another thread
//copy( m_input, m_process.getOutputStream() );
}
}
/**
* Process the standard output of process.
* Reading it and sending it to user specified stream
* or into the void.
*/
private void processStandardOutput()
{
final InputStream input = m_process.getInputStream();
copy( input, m_output );
}
/**
* Process the standard error of process.
* Reading it and sending it to user specified stream
* or into the void.
*/
private void processStandardError()
{
final InputStream input = m_process.getInputStream();
copy( input, m_error );
}
/**
* Copy data from specified input stream to output stream if
* output stream exists. The size of data that should be attempted
* to read is determined by calling available() on input stream.
*/
private void copy( final InputStream input,
final OutputStream output )
{
try
{
final int available = input.available();
if( 0 >= available ) return;
final byte[] data = new byte[ available ];
final int read = input.read( data );
if( null != output )
{
output.write( data, 0, read );
}
}
catch( final IOException ioe )
{
final String message = "Error processing streams";
getLogger().error( message, ioe );
}
}
}
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>