|
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.
|