/* * $Id$ * * Copyright (C) 2003-2015 JNode.org * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library 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 Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; If not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package org.jnode.shell; /** * The CommandThreadImpl class extends Thread with to implement CommandThread API. * * @author crawley@jnode.org */ public class CommandThreadImpl extends Thread implements CommandThread { private ThreadExitListener listener; private CommandRunnable runner; private Throwable terminatingException; private UncaughtExceptionHandler myUncaughtExceptionHandler = new UncaughtExceptionHandler() { public void uncaughtException(Thread thr, Throwable exc) { synchronized (CommandThreadImpl.this) { terminatingException = exc; } } }; /** * @param group the parent group for the thread * @param runner the runnable that will run the command * @param name a thread name * @param size the threads stack size */ public CommandThreadImpl(ThreadGroup group, CommandRunnable runner, String name, long size) { super(group, runner, name, size); this.runner = runner; setUncaughtExceptionHandler(myUncaughtExceptionHandler); } /** * @param group the parent group for the thread * @param runner the Runnable that will run the command * @param name the thread name */ public CommandThreadImpl(ThreadGroup group, CommandRunnable runner, String name) { super(group, runner, name); this.runner = runner; setUncaughtExceptionHandler(myUncaughtExceptionHandler); } /** * @param runner the Runnable that will run the command * @param name the thread name */ public CommandThreadImpl(CommandRunnable runner, String name) { super(runner, name); this.runner = runner; } @Override public void run() { try { super.run(); } finally { runner.flushStreams(); if (listener != null) { listener.notifyThreadExited(this); } } } public void start(ThreadExitListener listener) { this.listener = listener; super.start(); } public Runnable getRunner() { return this.runner; } public int getReturnCode() { return this.runner.getRC(); } @SuppressWarnings("deprecation") @Override public void stop(ThreadDeath threadDeath) { // FIXME - This is unsafe because the thread being killed could be in the // middle of updating some critical system data structure. We should // probably throw an exception. super.stop(threadDeath); } public void waitFor() { try { join(); } catch (InterruptedException ie) { //ignore } } @Override public synchronized Throwable getTerminatingException() { return (terminatingException != null) ? terminatingException : runner.getTerminatingException(); } }