From: <ls...@us...> - 2008-10-06 07:56:27
|
Revision: 4607 http://jnode.svn.sourceforge.net/jnode/?rev=4607&view=rev Author: lsantha Date: 2008-10-06 07:56:13 +0000 (Mon, 06 Oct 2008) Log Message: ----------- Progress with isolates. Modified Paths: -------------- trunk/core/src/classpath/ext/javax/isolate/Isolate.java trunk/core/src/classpath/ext/javax/isolate/IsolateStatus.java trunk/core/src/core/org/jnode/vm/isolate/DataLinkMessage.java trunk/core/src/core/org/jnode/vm/isolate/LinkMessageFactory.java trunk/core/src/core/org/jnode/vm/isolate/LinkMessageImpl.java trunk/core/src/core/org/jnode/vm/isolate/StatusLinkMessage.java trunk/core/src/core/org/jnode/vm/isolate/VmIsolate.java trunk/core/src/test/org/jnode/test/core/IsolateTest.java trunk/shell/src/shell/org/jnode/shell/isolate/IsolateCommandThreadImpl.java Added Paths: ----------- trunk/core/src/core/org/jnode/vm/isolate/IsolateStatusImpl.java trunk/core/src/test/org/jnode/test/core/StatusLinkTest.java Modified: trunk/core/src/classpath/ext/javax/isolate/Isolate.java =================================================================== --- trunk/core/src/classpath/ext/javax/isolate/Isolate.java 2008-10-05 06:54:44 UTC (rev 4606) +++ trunk/core/src/classpath/ext/javax/isolate/Isolate.java 2008-10-06 07:56:13 UTC (rev 4607) @@ -35,11 +35,11 @@ /** The actual isolate implementation */ private final VmIsolate impl; + //todo hide this constructor /** * Constructor for the root isolate. * - * @param mainClass - * @param args + * @param impl the JNode speciffic isolate implementation */ public Isolate(VmIsolate impl) { this.impl = impl; @@ -51,10 +51,8 @@ * @param mainClass * @param args */ - public Isolate(String mainClass, String[] args) { - this(new StreamBindings(), - (Properties) AccessController.doPrivileged(new GetPropertiesAction()), - mainClass, args); + public Isolate(String mainClass, String... args) { + this(new StreamBindings(), AccessController.doPrivileged(new GetPropertiesAction()), mainClass, args); } /** @@ -64,22 +62,20 @@ * @param args * @param properties */ - public Isolate(Properties properties, String mainClass, String[] args) { + public Isolate(Properties properties, String mainClass, String... args) { this(new StreamBindings(), properties, mainClass, args); } /** * Initialize this instance. - * - * @param mainClass - * @param mainArgs + * * @param bindings * @param properties + * @param mainClass + * @param args */ - public Isolate(StreamBindings bindings, Properties properties, - String mainClass, String[] args) { - this.impl = new VmIsolate(this, bindings.getBindings(), properties, - mainClass, args); + public Isolate(StreamBindings bindings, Properties properties, String mainClass, String... args) { + this.impl = new VmIsolate(this, bindings.getBindings(), properties, mainClass, args); } /** @@ -119,53 +115,61 @@ } /** - * Has this isolate reached the exited state. + * Gets a new Link associated with this Isolate from which the current + * isolate can receive status link messages. * * @return + * @throws ClosedLinkException */ - public boolean hasExited() { - return impl.hasExited(); + public Link newStatusLink() throws ClosedLinkException { + return impl.newStatusLink(currentIsolate().impl); } /** - * Has this isolate reached the terminated state. + * Start this isolate. * - * @return + * @param links + * @throws IsolateStartupException */ - public boolean hasTerminated() { - return impl.hasTerminated(); + public void start(Link... links) throws IsolateStartupException { + impl.start(this, links); } /** - * Has this isolate reached the started state. + * Returns an array of active Isolate objects. + * The array contains one entry for each isolate in the invoker's aggregate that has been started but has not yet + * terminated. New isolates may have been constructed or existing ones terminated by the time method returns. + * + * @return the active Isolate objects present at the time of the call * - * @return + * @throws SecurityException if a security manager is present and permission to query isolates is denied */ - public boolean hasStarted() { - return impl.hasStarted(); + public static Isolate[] getIsolates() { + //todo implement it + throw new UnsupportedOperationException(); } /** - * Gets a new Link associated with this Isolate from which the current - * isolate can receive status link messages. + * Returns the name of the main class of this isolate. * - * @return - * @throws ClosedLinkException + * @return the name of the main class of this isolate */ - public Link newStatusLink() throws ClosedLinkException { - return impl.newStatusLink(currentIsolate().impl); + public String getMainClassName() { + return impl.getMainClassName(); } /** - * Start this isolate. + * Returns the current state of the isolate. + * + * @return the current state of an isolate * - * @param messages - * @throws IsolateStartupException + * @throws IllegalStateException if called before the isolate is started + * @throws SecurityException if a security manager is present and permission to query isolates is denied */ - public void start(Link... links) throws IsolateStartupException { - impl.start(this, links); + public IsolateStatus.State getState() { + return impl.getIsolateState(); } - + /** * Retrieves a copy of the Link array passed to start() by the current * isolate's creator. Modification of this array will have no effect on @@ -180,6 +184,7 @@ return VmIsolate.getLinks(); } + //todo hide this method /** * Gets the implementation instance. * @@ -188,4 +193,10 @@ final VmIsolate getImpl() { return impl; } + + @Override + public String toString() { + //todo implement it + return super.toString(); //To change body of overridden methods use File | Settings | File Templates. + } } Modified: trunk/core/src/classpath/ext/javax/isolate/IsolateStatus.java =================================================================== --- trunk/core/src/classpath/ext/javax/isolate/IsolateStatus.java 2008-10-05 06:54:44 UTC (rev 4606) +++ trunk/core/src/classpath/ext/javax/isolate/IsolateStatus.java 2008-10-06 07:56:13 UTC (rev 4607) @@ -84,11 +84,11 @@ /** * Initialize this instance. - * @param source - * @param type + * @param state * @param exitReason + * @param exitCode */ - public IsolateStatus(State state, ExitReason exitReason, int exitCode) { + protected IsolateStatus(State state, ExitReason exitReason, int exitCode) { this.state = state; this.exitReason = exitReason; this.exitCode = exitCode; Modified: trunk/core/src/core/org/jnode/vm/isolate/DataLinkMessage.java =================================================================== --- trunk/core/src/core/org/jnode/vm/isolate/DataLinkMessage.java 2008-10-05 06:54:44 UTC (rev 4606) +++ trunk/core/src/core/org/jnode/vm/isolate/DataLinkMessage.java 2008-10-06 07:56:13 UTC (rev 4607) @@ -12,7 +12,7 @@ private final int length; - public DataLinkMessage(byte[] bytes, int offset, int length) { + DataLinkMessage(byte[] bytes, int offset, int length) { this.bytes = bytes; this.offset = offset; this.length = length; Added: trunk/core/src/core/org/jnode/vm/isolate/IsolateStatusImpl.java =================================================================== --- trunk/core/src/core/org/jnode/vm/isolate/IsolateStatusImpl.java (rev 0) +++ trunk/core/src/core/org/jnode/vm/isolate/IsolateStatusImpl.java 2008-10-06 07:56:13 UTC (rev 4607) @@ -0,0 +1,38 @@ +/* + * $ + */ +package org.jnode.vm.isolate; + +import javax.isolate.IsolateStatus; + +/** + * @author Levente S\u00e1ntha + */ +public class IsolateStatusImpl extends IsolateStatus implements Cloneable { + public IsolateStatusImpl(State state, ExitReason exitReason, int exitCode) { + super(state, exitReason, exitCode); + } + + @Override + protected Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + public IsolateStatusImpl copy() { + try { + return (IsolateStatusImpl) this.clone(); + } catch (CloneNotSupportedException x) { + throw new RuntimeException(x); + } + } + + @Override + public String toString() { + State s = getState(); + if(s.equals(State.EXITED)) { + return getState() + "(" + getExitReason() + "," + getExitCode(); + } else { + return getState().toString(); + } + } +} Modified: trunk/core/src/core/org/jnode/vm/isolate/LinkMessageFactory.java =================================================================== --- trunk/core/src/core/org/jnode/vm/isolate/LinkMessageFactory.java 2008-10-05 06:54:44 UTC (rev 4606) +++ trunk/core/src/core/org/jnode/vm/isolate/LinkMessageFactory.java 2008-10-06 07:56:13 UTC (rev 4607) @@ -28,9 +28,7 @@ * @param bytes * @return */ - public static LinkMessage newDataMessage(byte[] bytes, - int offset, - int length) { + public static LinkMessage newDataMessage(byte[] bytes, int offset, int length) { return new DataLinkMessage(bytes, offset, length); } Modified: trunk/core/src/core/org/jnode/vm/isolate/LinkMessageImpl.java =================================================================== --- trunk/core/src/core/org/jnode/vm/isolate/LinkMessageImpl.java 2008-10-05 06:54:44 UTC (rev 4606) +++ trunk/core/src/core/org/jnode/vm/isolate/LinkMessageImpl.java 2008-10-06 07:56:13 UTC (rev 4607) @@ -15,7 +15,7 @@ private boolean received = false; /** - * Close this message in the current isolate. + * Clone this message in the current isolate. * * @return */ Modified: trunk/core/src/core/org/jnode/vm/isolate/StatusLinkMessage.java =================================================================== --- trunk/core/src/core/org/jnode/vm/isolate/StatusLinkMessage.java 2008-10-05 06:54:44 UTC (rev 4606) +++ trunk/core/src/core/org/jnode/vm/isolate/StatusLinkMessage.java 2008-10-06 07:56:13 UTC (rev 4607) @@ -9,13 +9,13 @@ * 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 + * 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 + * 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., + * 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.vm.isolate; @@ -23,68 +23,35 @@ import javax.isolate.IsolateStatus; /** - * This class is use to transport status isolate information - * @author cr...@jn... + * @author Levente S\u00e1ntha */ -public final class StatusLinkMessage extends LinkMessageImpl { +final class StatusLinkMessage extends LinkMessageImpl { + private final IsolateStatusImpl status; - private final String state; - private final String exitReason; - private final int exitCode; - - /** - * Internal message constructor used by cloneMessage - * - * @param value - */ - private StatusLinkMessage(String state, String exitReason, int exitCode) { - this.state = state; - this.exitReason = exitReason; - this.exitCode = exitCode; + StatusLinkMessage(IsolateStatus status) { + this.status = (IsolateStatusImpl) status; } /** - * Message constructor used VmIsolate + * Clone this message in the current isolate. * - * @param value + * @return */ - public StatusLinkMessage(IsolateStatus.State state, IsolateStatus.ExitReason exitReason, - int exitCode) { - this(state.toString(), exitReason.toString(), exitCode); + LinkMessageImpl cloneMessage() { + return new StatusLinkMessage(status.copy()); } - /** - * @see org.jnode.vm.isolate.LinkMessageImpl#CloneMessage() - */ @Override - LinkMessageImpl cloneMessage() { - return new StatusLinkMessage(state, exitReason, exitCode); + public boolean containsStatus() { + return true; } - /** - * @see javax.isolate.LinkMessage#extract() - */ - @Override public Object extract() { - return extractStatus(); + return status; } - /** - * @see javax.isolate.LinkMessage#containsString() - */ @Override - public boolean containsStatus() { - return true; - } - - /** - * @see javax.isolate.LinkMessage#extractString() - */ - @Override public IsolateStatus extractStatus() { - return new IsolateStatus( - IsolateStatus.State.valueOf(state), - IsolateStatus.ExitReason.valueOf(exitReason), - exitCode); + return status; } } Modified: trunk/core/src/core/org/jnode/vm/isolate/VmIsolate.java =================================================================== --- trunk/core/src/core/org/jnode/vm/isolate/VmIsolate.java 2008-10-05 06:54:44 UTC (rev 4606) +++ trunk/core/src/core/org/jnode/vm/isolate/VmIsolate.java 2008-10-06 07:56:13 UTC (rev 4607) @@ -37,7 +37,6 @@ import javax.isolate.IsolateStartupException; import javax.isolate.IsolateStatus; import javax.isolate.Link; -import javax.isolate.LinkMessage; import javax.naming.NameNotFoundException; import org.jnode.naming.InitialNaming; @@ -95,6 +94,10 @@ */ private State state = State.CREATED; + private IsolateStatus.State isolateState; + private IsolateStatus.ExitReason exitReason; + private int exitCode; + /** * The root of the threadgroups for this isolate. */ @@ -159,7 +162,33 @@ */ @SharedStatics private enum State { - CREATED, STARTING, STARTED, EXITED, TERMINATED + CREATED(IsolateStatus.State.UNKNOWN), + + STARTING(IsolateStatus.State.STARTING), + + STARTED(IsolateStatus.State.STARTED), + + EXITING(IsolateStatus.State.EXITING), + + EXITED(IsolateStatus.State.EXITED), + + TERMINATING(IsolateStatus.State.EXITING), + + TERMINATED(IsolateStatus.State.EXITED), + + NEVERSTARTED(IsolateStatus.State.UNKNOWN), + + UNKNOWN(IsolateStatus.State.UNKNOWN); + + private final IsolateStatus.State isolateState; + + private State(IsolateStatus.State isolateState) { + this.isolateState = isolateState; + } + + IsolateStatus.State getIsolateState() { + return isolateState; + } } public static boolean walkIsolates(ObjectVisitor visitor) { @@ -352,12 +381,22 @@ //todo handle demon threads if (threadGroup.activeCount() > 0 || threadGroup.activeGroupCount() > 0) return; - + + changeState(State.EXITING); try { threadGroup.destroy(); } catch (Throwable t) { t.printStackTrace(); } + + this.exitCode = status; + if(currentIsolate() == this) { + //todo implement: IMPLICIT_EXIT, UNCAUGHT_EXCEPTION + this.exitReason = IsolateStatus.ExitReason.SELF_EXIT; + } else { + this.exitReason = IsolateStatus.ExitReason.OTHER_EXIT; + } + changeState(State.EXITED); StaticData.isolates.remove(this); } @@ -370,8 +409,9 @@ @SuppressWarnings("deprecation") public final void halt(Isolate isolate, int status) { testIsolate(isolate); + changeState(State.EXITING); switch (state) { - case STARTED: + case EXITING: threadGroup.stop(); break; } @@ -381,7 +421,13 @@ } catch (Throwable t) { t.printStackTrace(); } - changeState(State.TERMINATED); + this.exitCode = status; + if(currentIsolate() == this) { + this.exitReason = IsolateStatus.ExitReason.SELF_HALT; + } else { + this.exitReason = IsolateStatus.ExitReason.OTHER_HALT; + } + changeState(State.EXITED); StaticData.isolates.remove(this); } @@ -451,8 +497,9 @@ /** * Start this isolate. * - * @param messages - * @throws IsolateStartupException + * @param isolate the isolate to start + * @param links an array of links passed to the isolate on startup + * @throws IsolateStartupException on startup failure */ @PrivilegedActionPragma public synchronized final void start(Isolate isolate, Link[] links) @@ -518,9 +565,6 @@ final IsolateThread mainThread = new IsolateThread(threadGroup, this, piManager, stdout, stderr, stdin); - // Update the state of this isolate. - changeState(State.STARTED); - // Start the main thread. mainThread.start(); } @@ -538,7 +582,7 @@ task.run(); return; } - + synchronized(taskSync){ taskList.add(task); taskSync.notifyAll(); @@ -633,6 +677,9 @@ } }); + // Update the state of this isolate. + changeState(State.STARTED); + // Run main method. mainMethod.invoke(null, new Object[]{args}); } catch (Throwable ex) { @@ -756,6 +803,10 @@ return isolateLocalMap; } + public IsolateStatus.State getIsolateState() { + return isolateState; + } + /** * Create and return a new status link for this isolate and the supplied * receiver isolate. @@ -766,44 +817,32 @@ Link link = VmLink.newLink(this, receiver); VmLink vmLink = VmLink.fromLink(link); statusLinks.add(vmLink); - if (state == State.TERMINATED) { + if (isolateState != null && isolateState.equals(IsolateStatus.State.EXITED)) { // The spec says that we should immediately send a link message // if the isolate is already 'EXITED'. - sendStatus(vmLink, state); + sendStatus(vmLink, isolateState); } return link; } - - private synchronized void changeState(State newState) { - if (state != newState) { - this.state = newState; + + private synchronized boolean changeState(State newState) { + this.state = newState; + IsolateStatus.State newIsolateState = newState.getIsolateState(); + if (isolateState != newIsolateState) { + this.isolateState = newIsolateState; for (VmLink link : statusLinks) { - sendStatus(link, this.state); + sendStatus(link, this.isolateState); } } + return true; } - private void sendStatus(VmLink link, State state) { - IsolateStatus.State istate = null; - switch (state) { - case CREATED: - istate = IsolateStatus.State.UNKNOWN; - break; - case STARTING: - istate = IsolateStatus.State.STARTING; - break; - case STARTED: - istate = IsolateStatus.State.STARTED; - break; - case EXITED: - istate = IsolateStatus.State.EXITING; - break; - case TERMINATED: - istate = IsolateStatus.State.EXITED; - break; + private void sendStatus(VmLink link, IsolateStatus.State state) { + if(state.equals(IsolateStatus.State.EXITED)) { + org.jnode.vm.Unsafe.debugStackTrace(); + link.sendStatus(new StatusLinkMessage(new IsolateStatusImpl(state, exitReason, exitCode))); + } else { + link.sendStatus(new StatusLinkMessage(new IsolateStatusImpl(state, null, -1))); } - LinkMessage message = - new StatusLinkMessage(istate, IsolateStatus.ExitReason.IMPLICIT_EXIT, 0); - link.sendStatus(message); } } Modified: trunk/core/src/test/org/jnode/test/core/IsolateTest.java =================================================================== --- trunk/core/src/test/org/jnode/test/core/IsolateTest.java 2008-10-05 06:54:44 UTC (rev 4606) +++ trunk/core/src/test/org/jnode/test/core/IsolateTest.java 2008-10-06 07:56:13 UTC (rev 4607) @@ -5,6 +5,10 @@ import javax.isolate.Isolate; import javax.isolate.IsolateStartupException; +import javax.isolate.Link; +import javax.isolate.ClosedLinkException; +import javax.isolate.LinkMessage; +import javax.isolate.IsolateStatus; public class IsolateTest { Copied: trunk/core/src/test/org/jnode/test/core/StatusLinkTest.java (from rev 4600, trunk/core/src/test/org/jnode/test/core/LinkTest.java) =================================================================== --- trunk/core/src/test/org/jnode/test/core/StatusLinkTest.java (rev 0) +++ trunk/core/src/test/org/jnode/test/core/StatusLinkTest.java 2008-10-06 07:56:13 UTC (rev 4607) @@ -0,0 +1,64 @@ +/* + * $Id$ + */ +package org.jnode.test.core; + +import java.io.IOException; +import java.io.InterruptedIOException; +import javax.isolate.ClosedLinkException; +import javax.isolate.Isolate; +import javax.isolate.IsolateStartupException; +import javax.isolate.Link; +import javax.isolate.LinkMessage; +import javax.isolate.IsolateStatus; + +public class StatusLinkTest { + + public static void main(String[] args) throws IsolateStartupException, InterruptedIOException, IOException { + String clsName = ChildClass.class.getName(); + Isolate child = new Isolate(clsName); + Link link = child.newStatusLink(); + new Thread(new StatusMonitor(link)).start(); + child.start(); + } + + public static class StatusMonitor implements Runnable { + private final Link link; + + public StatusMonitor(Link link) { + this.link = link; + } + + public void run() { + try { + while (true) { + LinkMessage msg = link.receive(); + if(msg.containsStatus()) { + IsolateStatus is = msg.extractStatus(); + if(is.getState().equals(IsolateStatus.State.EXITED)) { + System.out.println("Message: state=" + is.getState() + " code=" + is.getExitCode() + + " reason=" + is.getExitReason()); + break; + } else { + System.out.println("Message: state=" + is.getState()); + } + } else { + System.out.println("Unknown message: " + msg); + } + } + } catch (Exception x) { + x.printStackTrace(); + } + } + } + + public static class ChildClass { + + public static void main(String[] args) throws InterruptedException { + System.out.println("Child: started"); + System.out.println("Child: sleeping 3 seconds"); + Thread.sleep(3000); + System.out.println("Child: exiting"); + } + } +} \ No newline at end of file Property changes on: trunk/core/src/test/org/jnode/test/core/StatusLinkTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:mergeinfo + Added: svn:eol-style + native Modified: trunk/shell/src/shell/org/jnode/shell/isolate/IsolateCommandThreadImpl.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/isolate/IsolateCommandThreadImpl.java 2008-10-05 06:54:44 UTC (rev 4606) +++ trunk/shell/src/shell/org/jnode/shell/isolate/IsolateCommandThreadImpl.java 2008-10-06 07:56:13 UTC (rev 4607) @@ -8,6 +8,7 @@ import java.io.OutputStream; import java.io.Reader; import java.io.Writer; +import java.io.InterruptedIOException; import java.net.Socket; import java.util.Properties; @@ -102,7 +103,8 @@ @Override public boolean isAlive() { - return isolate.hasStarted() && !isolate.hasExited(); + final IsolateStatus.State state = isolate.getState(); + return IsolateStatus.State.STARTED.equals(state); } @Override This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |