]> gcc.gnu.org Git - gcc.git/commitdiff
natNativeThread.cc: New file.
authorTom Tromey <tromey@cygnus.com>
Thu, 10 Feb 2000 20:31:48 +0000 (20:31 +0000)
committerTom Tromey <tromey@gcc.gnu.org>
Thu, 10 Feb 2000 20:31:48 +0000 (20:31 +0000)
* gnu/gcj/jni/natNativeThread.cc: New file.
* gnu/gcj/jni/NativeThread.java: New file.
* java/lang/Thread.java (data): Now a RawData.
* include/jvm.h (_Jv_GetCurrentJNIEnv, _Jv_SetCurrentJNIEnv):
Declare.
* Makefile.in: Rebuilt.
* Makefile.am (java/lang/Thread.h): New target.
(ordinary_java_source_files): Added NativeThread.java.
(nat_source_files): Added natNativeThread.cc.
* java/lang/natThread.cc: Include <jni.h>
(struct natThread): Added `jni_env' field.
(_Jv_GetCurrentJNIEnv): New function.
(_Jv_SetCurrentJNIEnv): Likewise.
(initialize_native): Initialize jni_env.
Include RawData.h.
* jni.cc (ThreadGroupClass): New define.
(_Jv_JNI_InvokeFunctions): New structure.
(JNI_GetCreatedJavaVMs): New function.
(the_vm): New global.
(JNI_GetDefaultJavaVMInitArgs): New function.
Include NativeThread.h.
(NativeThreadClass): New define.
(_Jv_JNI_EnsureLocalCapacity): Return JNI_ERR, not -1.
(_Jv_JNI_DestroyJavaVM): New function.
(_Jv_JNI_AttachCurrentThread): New function.
(_Jv_JNI_DetachCurrentThread): New function.
(_Jv_JNI_GetEnv): New function.
(JNI_CreateJavaVM): New function.
(_Jv_JNI_GetJavaVM): New function.
(_Jv_JNIFunctions): Added entry for GetJavaVM.
* include/jni.h (JavaVMAttachArgs): New structure.
(JNI_EDETACHED): New define.
(JNI_EVERSION): Likewise.
(JavaVM): Define properly.
(struct JNIInvokeInterface): New structure.
(class _Jv_JavaVM): New class.
(JNI_OnLoad, JNI_OnUnload): Declare.
(JNI_GetDefaultJavaVMInitArgs, JNI_CreateJavaVM,
JNI_GetCreatedJavaVMs): Declare.
(JavaVMInitArgs): New typedef.
(JavaVMOption): Likewise.
(JNI_ERR): New define.
(JNI_OK): Likewise.

From-SVN: r31901

libjava/ChangeLog
libjava/Makefile.am
libjava/Makefile.in
libjava/gnu/gcj/jni/NativeThread.java [new file with mode: 0644]
libjava/gnu/gcj/jni/natNativeThread.cc [new file with mode: 0644]
libjava/include/jni.h
libjava/include/jvm.h
libjava/java/lang/Thread.java
libjava/java/lang/natThread.cc
libjava/jni.cc

index 159853c6b0464535fbc8e049978729112d073311..91485fc98b09abb8175ce4041c9119327523b039 100644 (file)
@@ -1,3 +1,49 @@
+2000-02-10  Tom Tromey  <tromey@cygnus.com>
+
+       * gnu/gcj/jni/natNativeThread.cc: New file.
+       * gnu/gcj/jni/NativeThread.java: New file.
+       * java/lang/Thread.java (data): Now a RawData.
+       * include/jvm.h (_Jv_GetCurrentJNIEnv, _Jv_SetCurrentJNIEnv):
+       Declare.
+       * Makefile.in: Rebuilt.
+       * Makefile.am (java/lang/Thread.h): New target.
+       (ordinary_java_source_files): Added NativeThread.java.
+       (nat_source_files): Added natNativeThread.cc.
+       * java/lang/natThread.cc: Include <jni.h>
+       (struct natThread): Added `jni_env' field.
+       (_Jv_GetCurrentJNIEnv): New function.
+       (_Jv_SetCurrentJNIEnv): Likewise.
+       (initialize_native): Initialize jni_env.
+       Include RawData.h.
+       * jni.cc (ThreadGroupClass): New define.
+       (_Jv_JNI_InvokeFunctions): New structure.
+       (JNI_GetCreatedJavaVMs): New function.
+       (the_vm): New global.
+       (JNI_GetDefaultJavaVMInitArgs): New function.
+       Include NativeThread.h.
+       (NativeThreadClass): New define.
+       (_Jv_JNI_EnsureLocalCapacity): Return JNI_ERR, not -1.
+       (_Jv_JNI_DestroyJavaVM): New function.
+       (_Jv_JNI_AttachCurrentThread): New function.
+       (_Jv_JNI_DetachCurrentThread): New function.
+       (_Jv_JNI_GetEnv): New function.
+       (JNI_CreateJavaVM): New function.
+       (_Jv_JNI_GetJavaVM): New function.
+       (_Jv_JNIFunctions): Added entry for GetJavaVM.
+       * include/jni.h (JavaVMAttachArgs): New structure.
+       (JNI_EDETACHED): New define.
+       (JNI_EVERSION): Likewise.
+       (JavaVM): Define properly.
+       (struct JNIInvokeInterface): New structure.
+       (class _Jv_JavaVM): New class.
+       (JNI_OnLoad, JNI_OnUnload): Declare.
+       (JNI_GetDefaultJavaVMInitArgs, JNI_CreateJavaVM,
+       JNI_GetCreatedJavaVMs): Declare.
+       (JavaVMInitArgs): New typedef.
+       (JavaVMOption): Likewise.
+       (JNI_ERR): New define.
+       (JNI_OK): Likewise.
+
 2000-02-10  Andrew Haley  <aph@cygnus.com>
 
        * interpret.cc: Don't include fdlibm.h.
index 4abbeab42782f17bfee258719ab22fd3dd2f1e71..c22a2c8b99c56ac2c7464ec5e622ed02045f14ee 100644 (file)
@@ -221,6 +221,16 @@ java/lang/FirstThread.h: java/lang/FirstThread.class libgcj.zip
                -friend 'void _Jv_RunMain (const char*, int, const char **);' \
                $(basename $<)
 
+java/lang/Thread.h: java/lang/Thread.class libgcj.zip
+       $(GCJH) -classpath $(top_builddir) \
+               -prepend 'class _Jv_JNIEnv;' \
+## Eww.
+               -prepend 'extern "Java" { namespace gnu { namespace gcj { namespace jni { class NativeThread; } } } };' \
+               -friend '_Jv_JNIEnv * _Jv_GetCurrentJNIEnv ();' \
+               -friend 'void _Jv_SetCurrentJNIEnv (_Jv_JNIEnv *env);' \
+               -friend 'class gnu::gcj::jni::NativeThread;' \
+               $(basename $<)
+
 java/lang/String.h: java/lang/String.class libgcj.zip
        $(GCJH) -classpath $(top_builddir) \
            -friend 'jchar* _Jv_GetStringChars (jstring str);' \
@@ -512,6 +522,7 @@ built_java_source_files = java/lang/ConcreteProcess.java
 ## convert_source_files.  If the .java file has a hand-maintained
 ## header, please list it in special_java_source_files.
 ordinary_java_source_files =  $(convert_source_files) \
+gnu/gcj/jni/NativeThread.java \
 gnu/gcj/runtime/MethodInvocation.java \
 gnu/gcj/runtime/VMClassLoader.java \
 gnu/gcj/text/BaseBreakIterator.java \
@@ -796,6 +807,7 @@ gnu/gcj/convert/natInput_EUCJIS.cc \
 gnu/gcj/convert/natInput_SJIS.cc \
 gnu/gcj/convert/natOutput_EUCJIS.cc \
 gnu/gcj/convert/natOutput_SJIS.cc \
+gnu/gcj/jni/natNativeThread.cc \
 java/io/natFile.cc \
 java/io/natFileDescriptor.cc \
 java/lang/natCharacter.cc \
index bf0ffec020314babb4696f7b97f5de2bce8066da..dada6e9f02821efb859f986b64b27b660336535a 100644 (file)
@@ -326,6 +326,7 @@ java/awt/peer/WindowPeer.java
 built_java_source_files = java/lang/ConcreteProcess.java
 
 ordinary_java_source_files = $(convert_source_files) \
+gnu/gcj/jni/NativeThread.java \
 gnu/gcj/runtime/MethodInvocation.java \
 gnu/gcj/runtime/VMClassLoader.java \
 gnu/gcj/text/BaseBreakIterator.java \
@@ -610,6 +611,7 @@ gnu/gcj/convert/natInput_EUCJIS.cc \
 gnu/gcj/convert/natInput_SJIS.cc \
 gnu/gcj/convert/natOutput_EUCJIS.cc \
 gnu/gcj/convert/natOutput_SJIS.cc \
+gnu/gcj/jni/natNativeThread.cc \
 java/io/natFile.cc \
 java/io/natFileDescriptor.cc \
 java/lang/natCharacter.cc \
@@ -730,7 +732,8 @@ LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
 DATA =  $(data_DATA) $(toolexeclib_DATA)
 
 DIST_COMMON =  README COPYING.LIB ChangeLog Makefile.am Makefile.in NEWS \
-THANKS acinclude.m4 aclocal.m4 configure configure.in libgcj.spec.in
+THANKS acconfig.h acinclude.m4 aclocal.m4 configure configure.in \
+include/config.h.in include/stamp-h.in libgcj.spec.in
 
 
 DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
@@ -752,8 +755,8 @@ DEP_FILES =  .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
 .deps/gnu/gcj/convert/Output_JavaSrc.P \
 .deps/gnu/gcj/convert/Output_SJIS.P .deps/gnu/gcj/convert/Output_UTF8.P \
 .deps/gnu/gcj/convert/Output_iconv.P \
-.deps/gnu/gcj/convert/UnicodeToBytes.P .deps/gnu/gcj/math/MPN.P \
-.deps/gnu/gcj/protocol/file/Connection.P \
+.deps/gnu/gcj/convert/UnicodeToBytes.P .deps/gnu/gcj/jni/NativeThread.P \
+.deps/gnu/gcj/math/MPN.P .deps/gnu/gcj/protocol/file/Connection.P \
 .deps/gnu/gcj/protocol/file/Handler.P \
 .deps/gnu/gcj/protocol/http/Connection.P \
 .deps/gnu/gcj/protocol/http/Handler.P \
@@ -955,6 +958,34 @@ config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
        $(SHELL) ./config.status --recheck
 $(srcdir)/configure: @MAINTAINER_MODE_TRUE@$(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
        cd $(srcdir) && $(AUTOCONF)
+
+include/config.h: include/stamp-h
+       @if test ! -f $@; then \
+               rm -f include/stamp-h; \
+               $(MAKE) include/stamp-h; \
+       else :; fi
+include/stamp-h: $(srcdir)/include/config.h.in $(top_builddir)/config.status
+       cd $(top_builddir) \
+         && CONFIG_FILES= CONFIG_HEADERS=include/config.h \
+            $(SHELL) ./config.status
+       @echo timestamp > include/stamp-h 2> /dev/null
+$(srcdir)/include/config.h.in: @MAINTAINER_MODE_TRUE@$(srcdir)/include/stamp-h.in
+       @if test ! -f $@; then \
+               rm -f $(srcdir)/include/stamp-h.in; \
+               $(MAKE) $(srcdir)/include/stamp-h.in; \
+       else :; fi
+$(srcdir)/include/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) acconfig.h
+       cd $(top_srcdir) && $(AUTOHEADER)
+       @echo timestamp > $(srcdir)/include/stamp-h.in 2> /dev/null
+
+mostlyclean-hdr:
+
+clean-hdr:
+
+distclean-hdr:
+       -rm -f include/config.h
+
+maintainer-clean-hdr:
 libgcj.spec: $(top_builddir)/config.status libgcj.spec.in
        cd $(top_builddir) && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
 
@@ -1393,31 +1424,33 @@ distclean-generic:
        -rm -f config.cache config.log stamp-h stamp-h[0-9]*
 
 maintainer-clean-generic:
-mostlyclean-am:  mostlyclean-toolexeclibLIBRARIES mostlyclean-compile \
-               mostlyclean-libtool mostlyclean-toolexeclibLTLIBRARIES \
+mostlyclean-am:  mostlyclean-hdr mostlyclean-toolexeclibLIBRARIES \
+               mostlyclean-compile mostlyclean-libtool \
+               mostlyclean-toolexeclibLTLIBRARIES \
                mostlyclean-binPROGRAMS mostlyclean-noinstPROGRAMS \
                mostlyclean-tags mostlyclean-depend mostlyclean-generic
 
 mostlyclean: mostlyclean-recursive
 
-clean-am:  clean-toolexeclibLIBRARIES clean-compile clean-libtool \
-               clean-toolexeclibLTLIBRARIES clean-binPROGRAMS \
-               clean-noinstPROGRAMS clean-tags clean-depend \
-               clean-generic mostlyclean-am clean-local
+clean-am:  clean-hdr clean-toolexeclibLIBRARIES clean-compile \
+               clean-libtool clean-toolexeclibLTLIBRARIES \
+               clean-binPROGRAMS clean-noinstPROGRAMS clean-tags \
+               clean-depend clean-generic mostlyclean-am clean-local
 
 clean: clean-recursive
 
-distclean-am:  distclean-toolexeclibLIBRARIES distclean-compile \
-               distclean-libtool distclean-toolexeclibLTLIBRARIES \
-               distclean-binPROGRAMS distclean-noinstPROGRAMS \
-               distclean-tags distclean-depend distclean-generic \
-               clean-am
+distclean-am:  distclean-hdr distclean-toolexeclibLIBRARIES \
+               distclean-compile distclean-libtool \
+               distclean-toolexeclibLTLIBRARIES distclean-binPROGRAMS \
+               distclean-noinstPROGRAMS distclean-tags \
+               distclean-depend distclean-generic clean-am
        -rm -f libtool
 
 distclean: distclean-recursive
        -rm -f config.status
 
-maintainer-clean-am:  maintainer-clean-toolexeclibLIBRARIES \
+maintainer-clean-am:  maintainer-clean-hdr \
+               maintainer-clean-toolexeclibLIBRARIES \
                maintainer-clean-compile maintainer-clean-libtool \
                maintainer-clean-toolexeclibLTLIBRARIES \
                maintainer-clean-binPROGRAMS \
@@ -1430,7 +1463,8 @@ maintainer-clean-am:  maintainer-clean-toolexeclibLIBRARIES \
 maintainer-clean: maintainer-clean-recursive
        -rm -f config.status
 
-.PHONY: mostlyclean-toolexeclibLIBRARIES distclean-toolexeclibLIBRARIES \
+.PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \
+mostlyclean-toolexeclibLIBRARIES distclean-toolexeclibLIBRARIES \
 clean-toolexeclibLIBRARIES maintainer-clean-toolexeclibLIBRARIES \
 uninstall-toolexeclibLIBRARIES install-toolexeclibLIBRARIES \
 mostlyclean-compile distclean-compile clean-compile \
@@ -1514,6 +1548,15 @@ java/lang/FirstThread.h: java/lang/FirstThread.class libgcj.zip
                -friend 'void _Jv_RunMain (const char*, int, const char **);' \
                $(basename $<)
 
+java/lang/Thread.h: java/lang/Thread.class libgcj.zip
+       $(GCJH) -classpath $(top_builddir) \
+               -prepend 'class _Jv_JNIEnv;' \
+               -prepend 'extern "Java" { namespace gnu { namespace gcj { namespace jni { class NativeThread; } } } };' \
+               -friend '_Jv_JNIEnv * _Jv_GetCurrentJNIEnv ();' \
+               -friend 'void _Jv_SetCurrentJNIEnv (_Jv_JNIEnv *env);' \
+               -friend 'class gnu::gcj::jni::NativeThread;' \
+               $(basename $<)
+
 java/lang/String.h: java/lang/String.class libgcj.zip
        $(GCJH) -classpath $(top_builddir) \
            -friend 'jchar* _Jv_GetStringChars (jstring str);' \
diff --git a/libjava/gnu/gcj/jni/NativeThread.java b/libjava/gnu/gcj/jni/NativeThread.java
new file mode 100644 (file)
index 0000000..9ed6d89
--- /dev/null
@@ -0,0 +1,28 @@
+// NativeThread.java - Wrapper for attached user threads.
+
+/* Copyright (C) 1998, 1999, 2000  Red Hat, Inc.
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+package gnu.gcj.jni;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date February 9, 2000
+ */
+
+public class NativeThread extends Thread
+{
+  public NativeThread (ThreadGroup g, String name)
+  {
+    super (g, null, name);
+    alive_flag = true;
+  }
+
+  // Call this to mark the thread as finished.
+  public native void finish ();
+}
diff --git a/libjava/gnu/gcj/jni/natNativeThread.cc b/libjava/gnu/gcj/jni/natNativeThread.cc
new file mode 100644 (file)
index 0000000..b26c95d
--- /dev/null
@@ -0,0 +1,24 @@
+// natNativeThread.cc - Native side of attached threads.
+
+/* Copyright (C) 1998, 1999, 2000  Red Hat, Inc.
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+// Written by Tom Tromey <tromey@cygnus.com>
+
+#include <config.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <gnu/gcj/jni/NativeThread.h>
+#include <java/lang/Thread.h>
+
+void
+gnu::gcj::jni::NativeThread::finish ()
+{
+  finish_ ();
+}
index fa2fddc5e0e1c46b2f7992fd90209e151e7e3c88..35477797f40bc366bb74826a5a6384bf8565aab6 100644 (file)
@@ -23,6 +23,7 @@ details.  */
 #include <gcj/javaprims.h>
 
 typedef struct _Jv_JNIEnv JNIEnv;
+typedef struct _Jv_JavaVM JavaVM;
 
 #define JNI_TRUE true
 #define JNI_FALSE false
@@ -59,6 +60,7 @@ typedef void *jfieldID;
 typedef void *jmethodID;
 
 typedef const struct JNINativeInterface *JNIEnv;
+typedef const struct JNIInvokeInterface *JavaVM;
 
 #define JNI_TRUE 1
 #define JNI_TRUE 0
@@ -76,6 +78,32 @@ typedef jobject jweak;
 #define JNI_COMMIT 1
 #define JNI_ABORT  2
 
+/* Error codes */
+#define JNI_OK            0
+#define JNI_ERR          -1
+#define JNI_EDETACHED    -2
+#define JNI_EVERSION     -3
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+/* These functions might be defined in libraries which we load; the
+   JNI implementation calls them at the appropriate times.  */
+extern jint JNI_OnLoad (JavaVM *, void *);
+extern void JNI_OnUnload (JavaVM *, void *);
+
+/* These functions are called by user code to start using the
+   invocation API.  */
+extern jint JNI_GetDefaultJavaVMInitArgs (void *);
+extern jint JNI_CreateJavaVM (JavaVM **, void **, void *);
+extern jint JNI_GetCreatedJavaVMs(JavaVM **, jsize, jsize *);
+
+#ifdef __cplusplus
+};
+#endif /* __cplusplus */
+
 typedef union jvalue
 {
   jboolean z;
@@ -99,9 +127,6 @@ typedef struct
   void *fnPtr;                 /* Sigh.  */
 } JNINativeMethod;
 
-/* FIXME: this is just a placeholder.  */
-typedef int JavaVM;
-
 struct JNINativeInterface
 {
   _Jv_func reserved0;
@@ -1402,4 +1427,74 @@ public:
 };
 #endif /* __cplusplus */
 
+/*
+ * Invocation API.
+ */
+
+struct JNIInvokeInterface
+{
+  _Jv_func reserved0;
+  _Jv_func reserved1;
+  _Jv_func reserved2;
+
+  jint (*DestroyJavaVM)         (JavaVM *);
+  jint (*AttachCurrentThread)   (JavaVM *, void **, void *);
+  jint (*DetachCurrentThread)   (JavaVM *);
+  jint (*GetEnv)                (JavaVM *, void **, jint);
+};
+
+#ifdef __cplusplus
+
+class _Jv_JavaVM
+{
+public:
+  const struct JNIInvokeInterface *functions;
+
+private:
+  /* FIXME: other fields.  */
+
+public:
+  jint DestroyJavaVM ()
+  { return functions->DestroyJavaVM (this); }
+
+  jint AttachCurrentThread (void **penv, void *args)
+  { return functions->AttachCurrentThread (this, penv, args); }
+
+  jint DetachCurrentThread ()
+  { return functions->DetachCurrentThread (this); }
+
+  jint GetEnv (void **penv, jint version)
+  { return functions->GetEnv (this, penv, version); }
+};
+#endif /* __cplusplus */
+
+typedef struct JavaVMAttachArgs
+{
+  jint version;                        /* Must be JNI_VERSION_1_2.  */
+  char *name;                  /* The name of the thread (or NULL).  */
+  jobject group;               /* Global ref of a ThreadGroup object
+                                  (or NULL).  */
+} JavaVMAttachArgs;
+
+typedef struct JavaVMOption
+{
+  char *optionString;
+  void *extraInfo;
+} JavaVMOption;
+
+typedef struct JavaVMInitArgs
+{
+  /* Must be JNI_VERSION_1_2.  */
+  jint version;
+
+  /* Number of options.  */
+  jint nOptions;
+
+  /* Options to the VM.  */
+  JavaVMOption *options;
+
+  /* Whether we should ignore unrecognized options.  */
+  jboolean ignoreUnrecognized;
+} JavaVMInitArgs;
+
 #endif /* __GCJ_JNI_H__ */
index 325fe9390958c4ce329220827989d07e97604f85..d21da78923a3e5d61996e55ceb828440bbb71c7f 100644 (file)
@@ -207,4 +207,8 @@ void *_Jv_FindSymbolInExecutable (const char *);
 /* Initialize JNI.  */
 extern void _Jv_JNI_Init (void);
 
+/* Get or set the per-thread JNIEnv used by the invocation API.  */
+_Jv_JNIEnv *_Jv_GetCurrentJNIEnv ();
+void _Jv_SetCurrentJNIEnv (_Jv_JNIEnv *);
+
 #endif /* __JAVA_JVM_H__ */
index 34921677c8a67186dfbdd58bb7bd4f104eddea85..7dbabcf56c51252f9fb12030a5c91f349e8e1f22 100644 (file)
@@ -1,6 +1,6 @@
 // Thread.java - Thread class.
 
-/* Copyright (C) 1998, 1999  Red Hat, Inc.
+/* Copyright (C) 1998, 1999, 2000  Red Hat, Inc.
 
    This file is part of libgcj.
 
@@ -10,6 +10,8 @@ details.  */
 
 package java.lang;
 
+import gnu.gcj.RawData;
+
 /**
  * @author Tom Tromey <tromey@cygnus.com>
  * @date August 24, 1998 
@@ -297,11 +299,8 @@ public class Thread implements Runnable
   private boolean interrupt_flag;
   private boolean alive_flag;
 
-  // This is a bit odd.  We need a way to represent some data that is
-  // manipulated only by the native side of this class.  We represent
-  // it as a Java object reference.  However, it is not actually a
-  // Java object.
-  private Object data;
+  // Our native data.
+  private RawData data;
 
   // Next thread number to assign.
   private static int nextThreadNumber = 0;
index 6870f02c50d55aa3472b8cf79405695eb3b3262a..741f2b587e8ec3adfadce801c88e804ff3f744ca 100644 (file)
@@ -1,6 +1,6 @@
 // natThread.cc - Native part of Thread class.
 
-/* Copyright (C) 1998, 1999  Red Hat, Inc.
+/* Copyright (C) 1998, 1999, 2000  Red Hat, Inc.
 
    This file is part of libgcj.
 
@@ -23,6 +23,9 @@ details.  */
 #include <java/lang/IllegalThreadStateException.h>
 #include <java/lang/InterruptedException.h>
 #include <java/lang/NullPointerException.h>
+#include <gnu/gcj/RawData.h>
+
+#include <jni.h>
 
 \f
 
@@ -40,6 +43,9 @@ struct natThread
   // This is private data for the thread system layer.
   _Jv_Thread_t *thread;
 
+  // Each thread has its own JNI object.
+  JNIEnv *jni_env;
+
   // All threads waiting to join this thread are linked together and
   // waiting on their respective `interrupt' condition variables.
   // When this thread exits, it notifies each such thread by
@@ -83,10 +89,13 @@ java::lang::Thread::initialize_native (void)
   // own finalizer then we will need to reinitialize this structure at
   // any "interesting" point.
   natThread *nt = (natThread *) _Jv_AllocBytes (sizeof (natThread));
-  data = (jobject) nt;
+  data = reinterpret_cast<gnu::gcj::RawData *> (nt);
   _Jv_MutexInit (&nt->interrupt_mutex);
   _Jv_CondInit (&nt->interrupt_cond);
   _Jv_ThreadInitData (&nt->thread, this);
+  // FIXME: if JNI_ENV is set we will want to free it.  It is
+  // malloc()d.
+  nt->jni_env = NULL;
   nt->joiner = 0;
   nt->next = 0;
 }
@@ -324,3 +333,20 @@ java::lang::Thread::yield (void)
 {
   _Jv_ThreadYield ();
 }
+
+JNIEnv *
+_Jv_GetCurrentJNIEnv ()
+{
+  java::lang::Thread *t = _Jv_ThreadCurrent ();
+  if (t == NULL)
+    return NULL;
+  return ((natThread *) t->data)->jni_env;
+}
+
+void
+_Jv_SetCurrentJNIEnv (JNIEnv *env)
+{
+  java::lang::Thread *t = _Jv_ThreadCurrent ();
+  JvAssert (t != NULL);
+  ((natThread *) t->data)->jni_env = env;
+}
index b6728e5ab8622d6a8cdfffe098e49a4db55fb953..6beb6f7f8a49474dd9d8af132fa56b2c854fdfa9 100644 (file)
@@ -36,6 +36,7 @@ details.  */
 #include <java/lang/OutOfMemoryError.h>
 #include <java/util/Hashtable.h>
 #include <java/lang/Integer.h>
+#include <gnu/gcj/jni/NativeThread.h>
 
 #include <gcj/method.h>
 #include <gcj/field.h>
@@ -51,6 +52,10 @@ extern java::lang::Class ObjectClass;
 extern java::lang::Class ThrowableClass;
 #define MethodClass _CL_Q44java4lang7reflect6Method
 extern java::lang::Class MethodClass;
+#define ThreadGroupClass _CL_Q34java4lang11ThreadGroup
+extern java::lang::Class ThreadGroupClass;
+#define NativeThreadClass _CL_Q43gnu3gcj3jni12NativeThread
+extern java::lang::Class ThreadGroupClass;
 
 // This enum is used to select different template instantiations in
 // the invocation code.
@@ -62,8 +67,9 @@ enum invocation_type
   constructor
 };
 
-// Forward declaration.
+// Forward declarations.
 extern struct JNINativeInterface _Jv_JNIFunctions;
+extern struct JNIInvokeInterface _Jv_JNI_InvokeFunctions;
 
 // Number of slots in the default frame.  The VM must allow at least
 // 16.
@@ -89,6 +95,9 @@ struct _Jv_JNI_LocalFrame
 // This holds a reference count for all local and global references.
 static java::util::Hashtable *ref_table;
 
+// The only VM.
+static JavaVM *the_vm;
+
 \f
 
 void
@@ -178,7 +187,7 @@ _Jv_JNI_EnsureLocalCapacity (JNIEnv *env, jint size)
     {
       // FIXME: exception processing.
       env->ex = new java::lang::OutOfMemoryError;
-      return -1;
+      return JNI_ERR;
     }
 
   frame->marker = true;
@@ -1380,6 +1389,238 @@ _Jv_JNIMethod::call (ffi_cif *cif, void *ret, ffi_raw *args, void *__this)
 
 \f
 
+//
+// Invocation API.
+//
+
+// An internal helper function.
+static jint
+_Jv_JNI_AttachCurrentThread (JavaVM *, jstring name, void **penv, void *args)
+{
+  JavaVMAttachArgs *attach = reinterpret_cast<JavaVMAttachArgs *> (args);
+  java::lang::ThreadGroup *group = NULL;
+
+  if (attach)
+    {
+      // FIXME: do we really want to support 1.1?
+      if (attach->version != JNI_VERSION_1_2
+         && attach->version != JNI_VERSION_1_1)
+       return JNI_EVERSION;
+
+      JvAssert ((&ThreadGroupClass)->isInstance (attach->group));
+      group = reinterpret_cast<java::lang::ThreadGroup *> (attach->group);
+    }
+
+  // Attaching an already-attached thread is a no-op.
+  if (_Jv_ThreadCurrent () != NULL)
+    return 0;
+
+  // FIXME: NULL return?
+  JNIEnv *env = (JNIEnv *) _Jv_MallocUnchecked (sizeof (JNIEnv));
+  env->p = &_Jv_JNIFunctions;
+  env->ex = NULL;
+  env->klass = NULL;
+  // FIXME: NULL return?
+  env->locals
+    = (_Jv_JNI_LocalFrame *) _Jv_MallocUnchecked (sizeof (_Jv_JNI_LocalFrame)
+                                                 + (FRAME_SIZE
+                                                    * sizeof (jobject)));
+  *penv = reinterpret_cast<void *> (env);
+
+  java::lang::Thread *t = new gnu::gcj::jni::NativeThread (group, name);
+  t = t;                       // Avoid compiler warning.  Eww.
+  _Jv_SetCurrentJNIEnv (env);
+
+  return 0;
+}
+
+// This is the one actually used by JNI.
+static jint
+_Jv_JNI_AttachCurrentThread (JavaVM *vm, void **penv, void *args)
+{
+  return _Jv_JNI_AttachCurrentThread (vm, NULL, penv, args);
+}
+
+static jint
+_Jv_JNI_DestroyJavaVM (JavaVM *vm)
+{
+  JvAssert (the_vm && vm == the_vm);
+
+  JNIEnv *env;
+  if (_Jv_ThreadCurrent () != NULL)
+    {
+      jint r = _Jv_JNI_AttachCurrentThread (vm,
+                                           JvNewStringLatin1 ("main"),
+                                           reinterpret_cast<void **> (&env),
+                                           NULL);
+      if (r < 0)
+       return r;
+    }
+  else
+    env = _Jv_GetCurrentJNIEnv ();
+
+  _Jv_ThreadWait ();
+
+  // Docs say that this always returns an error code.
+  return JNI_ERR;
+}
+
+static jint
+_Jv_JNI_DetachCurrentThread (JavaVM *)
+{
+  java::lang::Thread *t = _Jv_ThreadCurrent ();
+  if (t == NULL)
+    return JNI_EDETACHED;
+
+  // FIXME: we only allow threads attached via AttachCurrentThread to
+  // be detached.  I have no idea how we could implement detaching
+  // other threads, given the requirement that we must release all the
+  // monitors.  That just seems evil.
+  JvAssert ((&NativeThreadClass)->isInstance (t));
+
+  // FIXME: release the monitors.  We'll take this to mean all
+  // monitors acquired via the JNI interface.  This means we have to
+  // keep track of them.
+
+  gnu::gcj::jni::NativeThread *nt
+    = reinterpret_cast<gnu::gcj::jni::NativeThread *> (t);
+  nt->finish ();
+
+  return 0;
+}
+
+static jint
+_Jv_JNI_GetEnv (JavaVM *, void **penv, jint version)
+{
+  if (_Jv_ThreadCurrent () == NULL)
+    {
+      *penv = NULL;
+      return JNI_EDETACHED;
+    }
+
+  // FIXME: do we really want to support 1.1?
+  if (version != JNI_VERSION_1_2 && version != JNI_VERSION_1_1)
+    {
+      *penv = NULL;
+      return JNI_EVERSION;
+    }
+
+  *penv = (void *) _Jv_GetCurrentJNIEnv ();
+  return 0;
+}
+
+jint
+JNI_GetDefaultJavaVMInitArgs (void *args)
+{
+  jint version = * (jint *) args;
+  // Here we only support 1.2.
+  if (version != JNI_VERSION_1_2)
+    return JNI_EVERSION;
+
+  JavaVMInitArgs *ia = reinterpret_cast<JavaVMInitArgs *> (args);
+  ia->version = JNI_VERSION_1_2;
+  ia->nOptions = 0;
+  ia->options = NULL;
+  ia->ignoreUnrecognized = true;
+
+  return 0;
+}
+
+jint
+JNI_CreateJavaVM (JavaVM **vm, void **penv, void *args)
+{
+  JvAssert (! the_vm);
+  // FIXME: synchronize
+  JavaVM *nvm = (JavaVM *) _Jv_MallocUnchecked (sizeof (JavaVM));
+  if (nvm == NULL)
+    return JNI_ERR;
+  nvm->functions = &_Jv_JNI_InvokeFunctions;
+
+  // Parse the arguments.
+  if (args != NULL)
+    {
+      jint version = * (jint *) args;
+      // We only support 1.2.
+      if (version != JNI_VERSION_1_2)
+       return JNI_EVERSION;
+      JavaVMInitArgs *ia = reinterpret_cast<JavaVMInitArgs *> (args);
+      for (int i = 0; i < ia->nOptions; ++i)
+       {
+         if (! strcmp (ia->options[i].optionString, "vfprintf")
+             || ! strcmp (ia->options[i].optionString, "exit")
+             || ! strcmp (ia->options[i].optionString, "abort"))
+           {
+             // We are required to recognize these, but for now we
+             // don't handle them in any way.  FIXME.
+             continue;
+           }
+         else if (! strncmp (ia->options[i].optionString,
+                             "-verbose", sizeof ("-verbose") - 1))
+           {
+             // We don't do anything with this option either.  We
+             // might want to make sure the argument is valid, but we
+             // don't really care all that much for now.
+             continue;
+           }
+         else if (! strncmp (ia->options[i].optionString, "-D", 2))
+           {
+             // FIXME.
+             continue;
+           }
+         else if (ia->ignoreUnrecognized)
+           {
+             if (ia->options[i].optionString[0] == '_'
+                 || ! strncmp (ia->options[i].optionString, "-X", 2))
+               continue;
+           }
+
+         return JNI_ERR;
+       }
+    }
+
+  jint r =_Jv_JNI_AttachCurrentThread (nvm, penv, NULL);
+  if (r < 0)
+    return r;
+
+  the_vm = nvm;
+  *vm = the_vm;
+  return 0;
+}
+
+jint
+JNI_GetCreatedJavaVMs (JavaVM **vm_buffer, jsize buf_len, jsize *n_vms)
+{
+  JvAssert (buf_len > 0);
+  // We only support a single VM.
+  if (the_vm != NULL)
+    {
+      vm_buffer[0] = the_vm;
+      *n_vms = 1;
+    }
+  else
+    *n_vms = 0;
+  return 0;
+}
+
+jint
+_Jv_JNI_GetJavaVM (JNIEnv *, JavaVM **vm)
+{
+  // FIXME: synchronize
+  if (! the_vm)
+    {
+      JavaVM *nvm = (JavaVM *) _Jv_MallocUnchecked (sizeof (JavaVM));
+      if (nvm == NULL)
+       return JNI_ERR;
+      nvm->functions = &_Jv_JNI_InvokeFunctions;
+      the_vm = nvm;
+    }
+
+  *vm = the_vm;
+  return 0;
+}
+
+\f
+
 #define NOT_IMPL NULL
 #define RESERVED NULL
 
@@ -1614,7 +1855,7 @@ struct JNINativeInterface _Jv_JNIFunctions =
   NOT_IMPL /* UnregisterNatives */,
   _Jv_JNI_MonitorEnter,
   _Jv_JNI_MonitorExit,
-  NOT_IMPL /* GetJavaVM */,
+  _Jv_JNI_GetJavaVM,
 
   _Jv_JNI_GetStringRegion,
   _Jv_JNI_GetStringUTFRegion,
@@ -1628,3 +1869,15 @@ struct JNINativeInterface _Jv_JNIFunctions =
 
   _Jv_JNI_ExceptionCheck
 };
+
+struct JNIInvokeInterface _Jv_JNI_InvokeFunctions =
+{
+  RESERVED,
+  RESERVED,
+  RESERVED,
+
+  _Jv_JNI_DestroyJavaVM,
+  _Jv_JNI_AttachCurrentThread,
+  _Jv_JNI_DetachCurrentThread,
+  _Jv_JNI_GetEnv
+};
This page took 0.096444 seconds and 5 git commands to generate.