From: <ls...@us...> - 2008-10-15 20:18:47
|
Revision: 4637 http://jnode.svn.sourceforge.net/jnode/?rev=4637&view=rev Author: lsantha Date: 2008-10-15 20:18:40 +0000 (Wed, 15 Oct 2008) Log Message: ----------- Imroved external isolate stopping and extended StatusLinkTest. Modified Paths: -------------- trunk/core/src/classpath/ext/javax/isolate/Isolate.java trunk/core/src/core/org/jnode/vm/isolate/VmIsolate.java trunk/core/src/core/org/jnode/vm/scheduler/VmScheduler.java trunk/core/src/core/org/jnode/vm/scheduler/VmThread.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-15 18:57:18 UTC (rev 4636) +++ trunk/core/src/classpath/ext/javax/isolate/Isolate.java 2008-10-15 20:18:40 UTC (rev 4637) @@ -103,7 +103,7 @@ * @param status */ public void exit(int status) { - impl.exit(this, status); + impl.isolateExit(status); } /** Modified: trunk/core/src/core/org/jnode/vm/isolate/VmIsolate.java =================================================================== --- trunk/core/src/core/org/jnode/vm/isolate/VmIsolate.java 2008-10-15 18:57:18 UTC (rev 4636) +++ trunk/core/src/core/org/jnode/vm/isolate/VmIsolate.java 2008-10-15 20:18:40 UTC (rev 4637) @@ -371,17 +371,32 @@ return isolate; } - public final void exit(Isolate isolate, int status) { - exit0(isolate, status); + public final void isolateExit(int status) { + changeState(State.EXITING); + + this.exitCode = status; + if (currentIsolate() == this) { + this.exitReason = IsolateStatus.ExitReason.SELF_EXIT; + } else { + this.exitReason = IsolateStatus.ExitReason.OTHER_EXIT; + } + + stopAllThreads(); } public final void systemExit(Isolate isolate, int status) { //only this isolate may call this method testIsolate(isolate); + changeState(State.EXITING); + this.exitReason = IsolateStatus.ExitReason.SELF_EXIT; this.exitCode = status; + stopAllThreads(); + } + + private void stopAllThreads() { int ac = threadGroup.activeCount(); if (ac > 0) { Thread[] ta = new Thread[ac]; @@ -397,33 +412,13 @@ } } if (found) { - current.getVmThread().stop(null); + current.getVmThread().stop(new ThreadDeath()); + } else { + doExit(); } - } - } - - /** - * Request normal termination of this isolate. - * - * @param status - */ - public final void exit0(Isolate isolate, int status) { - //testIsolate(isolate); - //todo handle demon threads - if (threadGroup.activeCount() > 0 || threadGroup.activeGroupCount() > 0) - return; - - changeState(State.EXITING); - - 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; + //todo analyze this case } - - doExit(); } /** @@ -439,9 +434,8 @@ if (threadGroup.activeCount() > 0 || threadGroup.activeGroupCount() > 0) return; - changeState(State.EXITING); - if (exitReason == null) { + changeState(State.EXITING); exitReason = IsolateStatus.ExitReason.IMPLICIT_EXIT; this.exitCode = status; } @@ -451,8 +445,6 @@ /** * Request normal termination of this isolate. - * - * @param status */ public final void uncaughtExceptionExit() { //on this isolate may call this method Modified: trunk/core/src/core/org/jnode/vm/scheduler/VmScheduler.java =================================================================== --- trunk/core/src/core/org/jnode/vm/scheduler/VmScheduler.java 2008-10-15 18:57:18 UTC (rev 4636) +++ trunk/core/src/core/org/jnode/vm/scheduler/VmScheduler.java 2008-10-15 20:18:40 UTC (rev 4637) @@ -124,6 +124,10 @@ allThreadsLock.lock(); try { allThreadsQueue.remove(thread); + //todo recent change, more testing needed + //remove the thread from readyQueue and sleepQueue too + readyQueue.remove(thread); + sleepQueue.remove(thread); } finally { allThreadsLock.unlock(); } Modified: trunk/core/src/core/org/jnode/vm/scheduler/VmThread.java =================================================================== --- trunk/core/src/core/org/jnode/vm/scheduler/VmThread.java 2008-10-15 18:57:18 UTC (rev 4636) +++ trunk/core/src/core/org/jnode/vm/scheduler/VmThread.java 2008-10-15 20:18:40 UTC (rev 4637) @@ -390,10 +390,11 @@ if (javaThread != null) { javaThread.onExit(); //exit the current isolate if needed - if (ex instanceof ThreadDeath) + if (ex instanceof ThreadDeath) { VmIsolate.currentIsolate().implicitExit(0); - else + } else { VmIsolate.currentIsolate().uncaughtExceptionExit(); + } // Notify joining threads synchronized (javaThread) { javaThread.notifyAll(); Modified: trunk/core/src/test/org/jnode/test/core/StatusLinkTest.java =================================================================== --- trunk/core/src/test/org/jnode/test/core/StatusLinkTest.java 2008-10-15 18:57:18 UTC (rev 4636) +++ trunk/core/src/test/org/jnode/test/core/StatusLinkTest.java 2008-10-15 20:18:40 UTC (rev 4637) @@ -3,23 +3,51 @@ */ package org.jnode.test.core; -import java.io.IOException; import javax.isolate.Isolate; -import javax.isolate.IsolateStartupException; import javax.isolate.IsolateStatus; import javax.isolate.Link; import javax.isolate.LinkMessage; +import javax.isolate.ClosedLinkException; +import javax.isolate.IsolateStartupException; public class StatusLinkTest { - public static void main(String[] args) throws IsolateStartupException, IOException { - String clsName = ChildClass.class.getName(); - Isolate child = new Isolate(clsName); - Link link = child.newStatusLink(); - new Thread(new StatusMonitor(link)).start(); + public static void main(String[] args) throws Exception { + + runChild(ChildClass1.class); + + runChild(ChildClass2.class); + + runChild(ChildClass3.class); + + runChild(ChildClass4.class); + + runChild(ChildClass5.class); + + runChild(ChildClass6.class); + + Isolate child = new Isolate(ChildClass7.class.getName()); + new Thread(new StatusMonitor(child.newStatusLink()), "status-monitor").start(); child.start(); + + try { + Thread.sleep(100); + } finally { + child.exit(0); + } } + private static void runChild(Class<?> clazz) + throws ClosedLinkException, IsolateStartupException, InterruptedException { + Isolate child; + Thread moni; + child = new Isolate(clazz.getName()); + moni = new Thread(new StatusMonitor(child.newStatusLink()), "status-monitor"); + moni.start(); + child.start(); + moni.join(); + } + public static class StatusMonitor implements Runnable { private final Link link; @@ -33,13 +61,10 @@ LinkMessage msg = link.receive(); if (msg.containsStatus()) { IsolateStatus is = msg.extractStatus(); - System.out.println("Isolate status: " + is); + System.out.println("Got status message: " + is); + //org.jnode.vm.Unsafe.debug("Got status message: " + is + "\n"); 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); @@ -51,30 +76,140 @@ } } - public static class ChildClass { + public static class ChildClass1 { + public static void main(String[] args) throws InterruptedException { + System.out.println("Child: started"); + System.out.println("Child: sleeping 2 seconds"); + Thread.sleep(2000); + System.out.println("Child: exiting"); + } + } + public static class ChildClass2 { public static void main(String[] args) throws InterruptedException { System.out.println("Child: started"); - System.out.println("Child: sleeping 3 seconds"); - Thread.sleep(3000); - //if(true) - // throw new RuntimeException(); new Thread(new Runnable() { public void run() { try { System.out.println("Child thread: started"); - System.out.println("Child thread: sleeping 3 seconds"); - Thread.sleep(3000); - if (true) - throw new RuntimeException(); + System.out.println("Child thread: sleeping 2 seconds"); + Thread.sleep(2000); System.out.println("Child thread: exiting"); } catch (InterruptedException ie) { ie.printStackTrace(); } } - }).start(); + }, "child-thread2").start(); + System.out.println("Child: exiting"); + } + } + public static class ChildClass3 { + public static void main(String[] args) throws InterruptedException { + System.out.println("Child: started"); + new Thread(new Runnable() { + public void run() { + try { + System.out.println("Child thread: started"); + System.out.println("Child thread: sleeping 2 seconds"); + Thread.sleep(2000); + System.out.println("Child thread: throwing an exception"); + throw new RuntimeException(); + } catch (InterruptedException ie) { + ie.printStackTrace(); + } + } + }, "child-thread3").start(); + System.out.println("Child: exiting"); } } + + public static class ChildClass4 { + public static void main(String[] args) throws InterruptedException { + System.out.println("Child: started"); + new Thread(new Runnable() { + public void run() { + try { + System.out.println("Child thread: started"); + System.out.println("Child thread: sleeping 2 seconds"); + Thread.sleep(2000); + System.out.println("Child thread: calling System.exit()"); + System.exit(0); + System.out.println("Child thread: exiting"); + } catch (InterruptedException ie) { + ie.printStackTrace(); + } + } + }, "child-thread4").start(); + + System.out.println("Child: exiting"); + } + } + + public static class ChildClass5 { + public static void main(String[] args) throws InterruptedException { + System.out.println("Child: started"); + new Thread(new Runnable() { + public void run() { + try { + System.out.println("Child thread: started"); + System.out.println("Child thread: sleeping 2 seconds"); + Thread.sleep(2000); + System.out.println("Child thread: callng Runtime.halt()"); + Runtime.getRuntime().halt(0); + System.out.println("Child thread: exiting"); + } catch (InterruptedException ie) { + ie.printStackTrace(); + } + } + }, "child-thread5").start(); + + System.out.println("Child: exiting"); + } + } + + public static class ChildClass6 { + public static void main(String[] args) throws InterruptedException { + System.out.println("Child: started"); + new Thread(new Runnable() { + public void run() { + try { + System.out.println("Child thread: started"); + System.out.println("Child thread: sleeping 2 seconds"); + Thread.sleep(2000); + System.out.println("Child thread: calling Isolate.exit()"); + Isolate.currentIsolate().exit(0); + System.out.println("Child thread: exiting"); + } catch (InterruptedException ie) { + ie.printStackTrace(); + } + } + }, "child-thread6").start(); + + System.out.println("Child: exiting"); + } + } + + public static class ChildClass7 { + public static void main(String[] args) throws InterruptedException { + System.out.println("Child: started"); + new Thread(new Runnable() { + public void run() { + System.out.println("Child thread: started"); + System.out.println("Child thread: working ..."); + for(int i = 0; i < 100000; i ++) { + // System.out.println("Child thread: " + i); + Math.sin(i); + if(i % 100 == 0) { + //org.jnode.vm.Unsafe.debug("i=" + i + "\n"); + System.out.println("i=" + i); + } + } + System.out.println("Child thread: exiting"); + } + }, "child-thread7").start(); + System.out.println("Child: exiting"); + } + } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |