Permalink
Browse files

Process management: cleanup

  • Loading branch information...
1 parent b34bce7 commit e0397006650887ddb82c5b657b6a9ea2ec433315 @chocolateboy chocolateboy committed Nov 22, 2012
@@ -194,7 +194,7 @@ public SystemUtils getRegistry() {
}
/**Executes a new Process and creates a fork that waits for its results.
- * TODO:Extend explanation on where this is being used.
+ * TODO Extend explanation on where this is being used.
* @param name Symbolic name for the process to be launched, only used in the trace log
* @param error (boolean) Set to true if you want PMS to add error messages to the trace pane
* @param workDir (File) optional working directory to run the process in
@@ -1780,13 +1780,16 @@ public InputStream getInputStream(Range range, RendererConfiguration mediarender
if (externalProcess == null || externalProcess.isDestroyed()) {
LOGGER.info("Starting transcode/remux of " + getName());
+
externalProcess = getPlayer().launchTranscode(
getSystemName(),
this,
getMedia(),
- params);
+ params
+ );
+
if (params.waitbeforestart > 0) {
- LOGGER.trace("Sleeping for " + params.waitbeforestart + " milliseconds");
+ LOGGER.trace("Sleeping for {} milliseconds", params.waitbeforestart);
try {
Thread.sleep(params.waitbeforestart);
@@ -1843,8 +1846,7 @@ public void run() {
LOGGER.trace("External input stream instance is null... sounds not good, waiting 500ms");
try {
Thread.sleep(500);
- } catch (InterruptedException e) {
- }
+ } catch (InterruptedException e) { }
}
}
@@ -1860,6 +1862,7 @@ public void run() {
externalProcess.stopProcess();
}
};
+
new Thread(r, "Hanging External Process Stopper").start();
}
@@ -162,7 +162,7 @@ public void run() {
}
private void parseHeader() throws IOException {
- LOGGER.trace("Parsing AVI Stream");
+ LOGGER.trace("Parsing AVI stream");
String id = getString(stream, 4);
getBytes(stream, 4);
String type = getString(stream, 4);
@@ -288,7 +288,7 @@ private void parseHeader() throws IOException {
try {
command = getString(stream, 4);
} catch (Exception e) {
- LOGGER.trace("Error attendue: " + e.getMessage());
+ LOGGER.trace("Error reading stream: " + e.getMessage());
break;
}
@@ -386,7 +386,7 @@ private final int readBytes(InputStream input, int number) throws IOException {
if (read < number) {
if (read < 0) {
- throw new IOException("End of Stream");
+ throw new IOException("End of stream");
}
for (int i = read; i < number; i++) {
@@ -91,6 +91,10 @@ public ProcessWrapper launchTranscode(
// This process wraps the command that creates the named pipe
PipeProcess pipe = new PipeProcess(fifoName);
+ pipe.deleteLater(); // delete the named pipe later; harmless if it isn't created
+ ProcessWrapper mkfifo_process = pipe.getPipeProcess();
+ // start the process as early as possible
+ mkfifo_process.runInNewThread();
params.input_pipes[0] = pipe;
int nThreads = configuration.getNumberOfCpuCores();
@@ -147,23 +151,19 @@ public ProcessWrapper launchTranscode(
// now launch ffmpeg
ProcessWrapperImpl pw = new ProcessWrapperImpl(cmdArray, params);
- ProcessWrapper mkfifo_process = pipe.getPipeProcess();
- pw.attachProcess(mkfifo_process);
-
- // create the named pipe and wait briefly to allow it to be created
- mkfifo_process.runInNewThread();
+ pw.attachProcess(mkfifo_process); // clean up the mkfifo process when the transcode ends
+ // give the mkfifo process a little time
try {
Thread.sleep(200);
} catch (InterruptedException e) {
LOGGER.error("Thread interrupted while waiting for named pipe to be created", e);
}
- pipe.deleteLater();
-
- // launch transcode command and wait briefly to allow it to start
+ // launch the transcode command...
pw.runInNewThread();
+ // ... and wait briefly to allow it to start
try {
Thread.sleep(200);
} catch (InterruptedException e) {
@@ -25,6 +25,8 @@
import java.io.FileInputStream;
import java.io.IOException;
+@Deprecated
+// no longer used
public class BlockerFileInputStream extends UnusedInputStream {
private static final Logger logger = LoggerFactory.getLogger(BlockerFileInputStream.class);
private static final int CHECK_INTERVAL = 1000;
@@ -1,8 +1,11 @@
package net.pms.io;
+import org.apache.commons.io.IOUtils;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.io.InputStream;
import java.io.IOException;
import java.net.NetworkInterface;
import java.net.SocketException;
@@ -11,53 +14,50 @@
import java.util.regex.Pattern;
public class MacSystemUtils extends BasicSystemUtils {
- private final static Logger logger = LoggerFactory.getLogger(MacSystemUtils.class);
+ private final static Logger LOGGER = LoggerFactory.getLogger(MacSystemUtils.class);
- public MacSystemUtils() {
- }
+ public MacSystemUtils() { }
@Override
public void browseURI(String uri) {
try {
- // On OSX, open the given URI with the "open" command.
+ // On OS X, open the given URI with the "open" command.
// This will open HTTP URLs in the default browser.
Runtime.getRuntime().exec(new String[] { "open", uri });
-
} catch (IOException e) {
- logger.trace("Unable to open the given URI: " + uri + ".");
+ LOGGER.trace("Unable to open the given URI: {}", uri);
}
}
-
+
@Override
public boolean isNetworkInterfaceLoopback(NetworkInterface ni) throws SocketException {
return false;
}
/**
* Fetch the hardware address for a network interface.
- *
- * @param ni Interface to fetch the mac address for
- * @return the mac address as bytes, or null if it couldn't be fetched.
+ *
+ * @param ni Interface to fetch the MAC address for
+ * @return the MAC address as bytes, or null if it couldn't be fetched.
* @throws SocketException
- * This won't happen on Mac OS, since the NetworkInterface is
+ * This won't happen on OS X, since the NetworkInterface is
* only used to get a name.
*/
@Override
public byte[] getHardwareAddress(NetworkInterface ni) throws SocketException {
- // On Mac OS, fetch the hardware address from the command line tool "ifconfig".
+ // On Mac OS X, fetch the hardware address from the command line tool "ifconfig".
byte[] aHardwareAddress = null;
+ InputStream inputStream = null;
try {
- Process aProc = Runtime.getRuntime().exec(new String[] { "ifconfig", ni.getName(), "ether" });
- aProc.waitFor();
- OutputTextConsumer aConsumer = new OutputTextConsumer(aProc.getInputStream(), false);
- aConsumer.run();
- List<String> aLines = aConsumer.getResults();
+ Process process = Runtime.getRuntime().exec(new String[] { "ifconfig", ni.getName(), "ether" });
+ inputStream = process.getInputStream();
+ List<String> lines = IOUtils.readLines(inputStream);
String aMacStr = null;
Pattern aMacPattern = Pattern.compile("\\s*ether\\s*([a-d0-9]{2}:[a-d0-9]{2}:[a-d0-9]{2}:[a-d0-9]{2}:[a-d0-9]{2}:[a-d0-9]{2})");
- for (String aLine : aLines) {
- Matcher aMacMatcher = aMacPattern.matcher(aLine);
+ for (String line : lines) {
+ Matcher aMacMatcher = aMacPattern.matcher(line);
if (aMacMatcher.find()) {
aMacStr = aMacMatcher.group(1);
@@ -75,12 +75,11 @@ public boolean isNetworkInterfaceLoopback(NetworkInterface ni) throws SocketExce
}
}
} catch (IOException e) {
- logger.debug("Failed to execute ifconfig", e);
- } catch (InterruptedException e) {
- logger.debug("Interrupted while waiting for ifconfig", e);
- Thread.interrupted(); // XXX work around a Java bug - see ProcessUtil.waitFor()
+ LOGGER.warn("Failed to execute ifconfig", e);
+ } finally {
+ IOUtils.closeQuietly(inputStream);
}
- return aHardwareAddress;
- }
+ return aHardwareAddress;
+ }
}
@@ -26,7 +26,7 @@
import java.util.List;
public class OutputBufferConsumer extends OutputConsumer {
- private static final Logger logger = LoggerFactory.getLogger(OutputBufferConsumer.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(OutputBufferConsumer.class);
private BufferedOutputFile outputBuffer;
/**
@@ -49,23 +49,23 @@ public OutputBufferConsumer(InputStream inputStream, OutputParams params) {
public void run() {
try {
- //logger.trace("Starting read from pipe");
+ // LOGGER.trace("Starting read from pipe");
byte buf[] = new byte[PIPE_BUFFER_SIZE];
int n = 0;
while ((n = inputStream.read(buf)) > 0) {
- //logger.trace("Fetched " + n + " from pipe");
+ // LOGGER.trace("Fetched " + n + " from pipe");
outputBuffer.write(buf, 0, n);
}
- //logger.debug("Finished to read");
+ // LOGGER.debug("Finished to read");
} catch (IOException ioe) {
- logger.debug("Error consuming stream of spawned process: " + ioe.getMessage());
+ LOGGER.debug("Error consuming stream of spawned process: " + ioe.getMessage());
} finally {
- //logger.trace("Closing read from pipe");
+ // LOGGER.trace("Closing read from pipe");
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
- logger.debug("Caught exception", e);
+ LOGGER.debug("Caught exception", e);
}
}
}
@@ -18,6 +18,8 @@
*/
package net.pms.io;
+import org.apache.commons.io.IOUtils;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -35,11 +37,7 @@ public OutputConsumer(InputStream inputStream) {
@Deprecated
public void destroy() {
- try {
- inputStream.close();
- } catch (IOException e) {
- LOGGER.debug("Failed to close stream", e);
- }
+ IOUtils.closeQuietly(inputStream);
}
public abstract BufferedOutputFile getBuffer();
@@ -83,7 +83,6 @@ public OutputParams(PmsConfiguration configuration) {
}
timeseek = 0;
- outputFile = null;
env = null;
}
@@ -105,7 +104,7 @@ public String toString() {
+ losslessaudio + ", lossyaudio=" + lossyaudio + ", maxBufferSize=" + maxBufferSize
+ ", mediaRenderer=" + mediaRenderer + ", minBufferSize=" + minBufferSize + ", minFileSize="
+ minFileSize + ", no_videoencode=" + no_videoencode + ", noexitcheck=" + noexitcheck
- + ", outputFile=" + outputFile + ", output_pipes=" + Arrays.toString(output_pipes)
+ + ", output_pipes=" + Arrays.toString(output_pipes)
+ ", secondread_minsize=" + secondread_minsize + ", shift_scr=" + shift_scr + ", sid=" + sid
+ ", stdin=" + stdin + ", timeend=" + timeend + ", timeseek=" + timeseek + ", toFrame=" + toFrame
+ ", waitbeforestart=" + waitbeforestart + ", workDir=" + workDir + ", env=" + env + "]";
@@ -18,6 +18,9 @@
*/
package net.pms.io;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.io.LineIterator;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -28,8 +31,11 @@
import java.util.ArrayList;
import java.util.List;
+/**
+ * An input stream consumer that stores the consumed lines in a list and optionally logs each line.
+ */
public class OutputTextConsumer extends OutputConsumer {
- private static final Logger logger = LoggerFactory.getLogger(OutputTextConsumer.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(OutputTextConsumer.class);
private List<String> lines = new ArrayList<String>();
private Object linesLock = new Object();
private boolean log;
@@ -41,35 +47,26 @@ public OutputTextConsumer(InputStream inputStream, boolean log) {
}
public void run() {
- BufferedReader br = null;
+ LineIterator it = null;
+
try {
- br = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
- String line = null;
- int authorized = 10;
- while ((line = br.readLine()) != null) {
- if (line.length() > 0 && line.startsWith("[") && authorized > 0) {
- addLine(line);
- if (log) {
- logger.trace(line);
- }
- authorized--;
- } else if (line.length() > 0 && !line.startsWith("[") && !line.startsWith("100") && !line.startsWith("size") && !line.startsWith("frame") && !line.startsWith("Pos") && !line.startsWith("ERROR:") && !line.startsWith("BUFFER") && !line.startsWith("INITV")) {
+ it = IOUtils.lineIterator(inputStream, "UTF-8");
+
+ while (it.hasNext()) {
+ String line = it.nextLine();
+
+ if (line.length() > 0) {
addLine(line);
- if (log) {
- logger.trace(line);
- }
+ }
+
+ if (log) {
+ LOGGER.debug(line);
}
}
} catch (IOException ioe) {
- logger.debug("Error consuming stream of spawned process: " + ioe.getMessage());
+ LOGGER.debug("Error consuming input stream: " + ioe.getMessage());
} finally {
- if (br != null) {
- try {
- br.close();
- } catch (IOException e) {
- logger.debug("Caught exception", e);
- }
- }
+ LineIterator.closeQuietly(it); // clean up all associated resources
}
}
@@ -85,9 +82,11 @@ public BufferedOutputFile getBuffer() {
public List<String> getResults() {
List<String> clonedResults = new ArrayList<String>();
+
synchronized (linesLock) {
clonedResults.addAll(lines);
}
+
return clonedResults;
}
}
Oops, something went wrong.

0 comments on commit e039700

Please sign in to comment.