[kaffe] Shutdown patch
Guilhem Lavaux
guilhem.lavaux@free.fr
Tue Jul 8 10:14:02 2003
--Boundary-00=_R1vC/E2SFryoV9P
Content-Type: Text/Plain;
charset="us-ascii"
Content-Transfer-Encoding: quoted-printable
Content-Description: clearsigned data
Content-Disposition: inline
Hi,
This patch adds the ShutdownHook (Java 1.3) feature to kaffe. Here is a=20
Changelog:
* libraries/clib/native/Application.c,=20
libraries/javalib/kaffe/lang/Application.java: removed
* libraries/clib/native/Runtime.c: renamed exitInternal() into exit0()
* libraries/javalib/java/lang/Runtime.java (exitInternal, addShutdownHook,=
=20
removeShutdownHook, exitJavaCleanup, runShutdownHooks): implement the=20
Shutdown hook Java 1.3 feature, removed kaffe/lang/Application.
* libraries/javalib/java/lang/System.java (exitJavaCleanup): Added a hook f=
or=20
java.lang.Runtime.exitJavaCleanup.
* kaffe/kaffevm/threads.c: Call System.exitJavaCleanup() before final exit.
If you check it in, you will first need to delete kaffe/lang/Application.ja=
va=20
and native/Application.c as mentioned. Hope it's allright.
Cheers,
Guilhem.
--Boundary-00=_R1vC/E2SFryoV9P
Content-Type: text/x-diff;
charset="us-ascii";
name="shutdown.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="shutdown.patch"
Index: include/Makefile.am
===================================================================
RCS file: /cvs/kaffe/kaffe/include/Makefile.am,v
retrieving revision 1.38
diff -u -3 -p -r1.38 Makefile.am
--- include/Makefile.am 13 Jun 2003 00:32:00 -0000 1.38
+++ include/Makefile.am 8 Jul 2003 17:10:20 -0000
@@ -104,7 +104,6 @@ NOINSTALL_JNI_DERIVED_HDRS = \
kaffe_io_ByteToCharIconv.h \
kaffe_io_CharToByteDefault.h \
kaffe_io_CharToByteIconv.h \
- kaffe_lang_Application.h \
kaffe_lang_MemoryAdvice.h \
kaffe_lang_UNIXProcess.h \
kaffe_management_JIT.h \
Index: kaffe/kaffevm/thread.c
===================================================================
RCS file: /cvs/kaffe/kaffe/kaffe/kaffevm/thread.c,v
retrieving revision 1.48
diff -u -3 -p -r1.48 thread.c
--- kaffe/kaffevm/thread.c 11 Jun 2003 16:54:14 -0000 1.48
+++ kaffe/kaffevm/thread.c 8 Jul 2003 17:10:20 -0000
@@ -34,6 +34,7 @@
#include "gc.h"
#include "jni.h"
#include "md.h"
+#include "java_lang_Runtime.h"
/* If not otherwise specified, assume at least 1MB for main thread */
#ifndef MAINSTACKSIZE
@@ -570,6 +571,10 @@ static
void
runfinalizer(void)
{
+ Hjava_lang_Runtime *runtime;
+
+ do_execute_java_method(SystemClass, "exitJavaCleanup",
+ "(Ljava/lang/Runtime;)V", NULL, true);
if (runFinalizerOnExit) {
invokeFinalizer();
}
Index: libraries/clib/native/Makefile.am
===================================================================
RCS file: /cvs/kaffe/kaffe/libraries/clib/native/Makefile.am,v
retrieving revision 1.20
diff -u -3 -p -r1.20 Makefile.am
--- libraries/clib/native/Makefile.am 26 Jun 2003 11:05:37 -0000 1.20
+++ libraries/clib/native/Makefile.am 8 Jul 2003 17:10:20 -0000
@@ -16,7 +16,6 @@ IO_SRCS = \
ObjectStreamClassImpl.c
LANG_SRCS = \
- Application.c \
Class.c \
ClassLoader.c \
Compiler.c \
Index: libraries/clib/native/Runtime.c
===================================================================
RCS file: /cvs/kaffe/kaffe/libraries/clib/native/Runtime.c,v
retrieving revision 1.19
diff -u -3 -p -r1.19 Runtime.c
--- libraries/clib/native/Runtime.c 29 May 2002 22:58:44 -0000 1.19
+++ libraries/clib/native/Runtime.c 8 Jul 2003 17:10:20 -0000
@@ -31,7 +31,7 @@ extern jboolean runFinalizerOnExit;
* Exit this VM
*/
void
-java_lang_Runtime_exitInternal(struct Hjava_lang_Runtime* r, jint v)
+java_lang_Runtime_exit0(struct Hjava_lang_Runtime* r, jint v)
{
EXIT (v);
}
Index: libraries/javalib/Klasses.jar.bootstrap
===================================================================
RCS file: /cvs/kaffe/kaffe/libraries/javalib/Klasses.jar.bootstrap,v
retrieving revision 1.20
diff -u -3 -p -r1.20 Klasses.jar.bootstrap
Binary files /tmp/cvsJ3t3rt and Klasses.jar.bootstrap differ
Index: libraries/javalib/essential.files
===================================================================
RCS file: /cvs/kaffe/kaffe/libraries/javalib/essential.files,v
retrieving revision 1.10
diff -u -3 -p -r1.10 essential.files
--- libraries/javalib/essential.files 28 Jun 2003 18:06:42 -0000 1.10
+++ libraries/javalib/essential.files 8 Jul 2003 17:10:23 -0000
@@ -283,7 +283,6 @@ kaffe/io/StdErrorStream.java
kaffe/io/StdInputStream.java
kaffe/io/StdOutputStream.java
kaffe/lang/AppClassLoader.java
-kaffe/lang/Application.java
kaffe/lang/ApplicationException.java
kaffe/lang/ApplicationResource.java
kaffe/lang/ClassPathReader.java
Index: libraries/javalib/java/lang/Runtime.java
===================================================================
RCS file: /cvs/kaffe/kaffe/libraries/javalib/java/lang/Runtime.java,v
retrieving revision 1.23
diff -u -3 -p -r1.23 Runtime.java
--- libraries/javalib/java/lang/Runtime.java 28 Jun 2003 18:06:41 -0000 1.23
+++ libraries/javalib/java/lang/Runtime.java 8 Jul 2003 17:10:23 -0000
@@ -17,6 +17,8 @@ import java.io.OutputStream;
import java.io.FileNotFoundException;
import java.util.StringTokenizer;
+import java.util.Vector;
+import java.util.Enumeration;
import kaffe.lang.ThreadStack;
@@ -37,6 +39,8 @@ public interface MemoryAdvice {
private static Runtime currentRuntime = new Runtime();
private static kaffe.lang.MemoryAdvice advice
= kaffe.lang.MemoryAdvice.getInstance();
+private static Vector shutdownHooks = new Vector(0);
+private static boolean VMShuttingDown = false;
private Runtime () {
}
@@ -81,26 +85,31 @@ public Process exec(String[] cmdarray, S
private native Process execInternal(String cmdary[], String envp[], File dir)
throws IOException;
+
+protected void exitJavaCleanup() {
+ runShutdownHooks();
+}
-public void exit(int status) {
+public void exit(int status) throws SecurityException {
SecurityManager sm = System.getSecurityManager();
if (sm != null)
sm.checkExit(status);
- // Handle application extensions - if this thread is part of an
- // application then we exit that rather than the whole thing.
- if (!kaffe.lang.Application.exit(status)) {
- exitInternal(status);
- }
- // kaffe.lang.Application.exit does not destroy the thread
- // that invoked exit(). We stop that thread now.
- Thread.currentThread().destroy();
+
+ /* First we cleanup the Virtual Machine */
+ exitJavaCleanup();
+ /* Now we run the VM exit function */
+ exit0(status);
}
-public void halt(int status) {
- exitInternal(status);
+public void halt(int status) throws SecurityException {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkExit(status);
+
+ exit0(status);
}
-native private void exitInternal(int status);
+native private void exit0(int status);
native public long freeMemory();
@@ -177,15 +186,68 @@ int waitForMemoryAdvice(int level) throw
return (advice.waitForOtherColor(level));
}
-public void addShutdownHook(Thread hook) {
- // XXX implement me
- System.err.println("WARNING: Not implemented method called " +
- getClass().getName() + ".addShutdownHook()");
+private void runShutdownHooks() {
+ Enumeration hook_enum;
+
+ /* According to Java 1.3 we need to run all hooks simultaneously
+ * and then wait for them.
+ */
+ synchronized (this) {
+ VMShuttingDown = true;
+ }
+ /* We start all threads at once as in the specification */
+ hook_enum = shutdownHooks.elements();
+ while (hook_enum.hasMoreElements()) {
+ Thread hook = (Thread)hook_enum.nextElement();
+
+ try {
+ hook.start();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /* Now we wait for each thread */
+ hook_enum = shutdownHooks.elements();
+ while (hook_enum.hasMoreElements()) {
+ Thread hook = (Thread)hook_enum.nextElement();
+
+ try {
+ hook.join();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
}
-public boolean removeShutdownHook(Thread hook) {
- // XXX implement me
- return false;
+public void addShutdownHook(Thread hook) throws IllegalArgumentException, IllegalStateException {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkPermission(new RuntimePermission("shutdownHooks"));
+
+ synchronized(this) {
+ if (VMShuttingDown)
+ throw new IllegalStateException("VM is shutting down.");
+ }
+ if (shutdownHooks.contains(hook))
+ throw new IllegalArgumentException("Thread already in shutdown queue.");
+ if (hook.isAlive() || hook.isInterrupted() || hook.isDied())
+ throw new IllegalArgumentException("Thread has already been started once.");
+
+ shutdownHooks.addElement(hook);
+}
+
+public boolean removeShutdownHook(Thread hook) throws IllegalStateException {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkPermission(new RuntimePermission("shutdownHooks"));
+
+ synchronized(this) {
+ if (VMShuttingDown)
+ throw new IllegalStateException("VM is shutting down.");
+ }
+
+ return shutdownHooks.removeElement(hook);
}
native public void runFinalization();
Index: libraries/javalib/java/lang/System.java
===================================================================
RCS file: /cvs/kaffe/kaffe/libraries/javalib/java/lang/System.java,v
retrieving revision 1.34
diff -u -3 -p -r1.34 System.java
--- libraries/javalib/java/lang/System.java 28 Jun 2003 18:06:41 -0000 1.34
+++ libraries/javalib/java/lang/System.java 8 Jul 2003 17:10:23 -0000
@@ -135,6 +135,10 @@ public static void runFinalizersOnExit(b
Runtime.getRuntime().runFinalizersOnExit(value);
}
+private static void exitJavaCleanup() {
+ Runtime.getRuntime().exitJavaCleanup();
+}
+
public static void setErr(PrintStream err) {
// XXX call security manager for RuntimePermission("SetIO")
setErr0(err);
Index: libraries/javalib/java/lang/Thread.java
===================================================================
RCS file: /cvs/kaffe/kaffe/libraries/javalib/java/lang/Thread.java,v
retrieving revision 1.40
diff -u -3 -p -r1.40 Thread.java
--- libraries/javalib/java/lang/Thread.java 24 May 2003 20:07:07 -0000 1.40
+++ libraries/javalib/java/lang/Thread.java 8 Jul 2003 17:10:23 -0000
@@ -274,6 +274,10 @@ public static boolean interrupted() {
return (i);
}
+protected final boolean isDied() {
+ return dying;
+}
+
public final boolean isAlive () {
return (started && !dying);
}
--Boundary-00=_R1vC/E2SFryoV9P--