summaryrefslogtreecommitdiff
path: root/libjava/gnu/gcj/runtime/natFirstThread.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/gnu/gcj/runtime/natFirstThread.cc')
-rw-r--r--libjava/gnu/gcj/runtime/natFirstThread.cc97
1 files changed, 96 insertions, 1 deletions
diff --git a/libjava/gnu/gcj/runtime/natFirstThread.cc b/libjava/gnu/gcj/runtime/natFirstThread.cc
index 458103c895a..c498ff84d78 100644
--- a/libjava/gnu/gcj/runtime/natFirstThread.cc
+++ b/libjava/gnu/gcj/runtime/natFirstThread.cc
@@ -1,6 +1,6 @@
// natFirstThread.cc - Implementation of FirstThread native methods.
-/* Copyright (C) 1998, 1999 Free Software Foundation
+/* Copyright (C) 1998, 1999, 2000 Free Software Foundation
This file is part of libgcj.
@@ -14,6 +14,7 @@ details. */
#include <gcj/cni.h>
#include <jvm.h>
+#include <jni.h>
#include <gnu/gcj/runtime/FirstThread.h>
#include <java/lang/Class.h>
@@ -22,16 +23,56 @@ details. */
#include <java/lang/reflect/Modifier.h>
#include <java/io/PrintStream.h>
+#ifdef ENABLE_JVMPI
+#include <jvmpi.h>
+#include <java/lang/ThreadGroup.h>
+#include <java/lang/UnsatisfiedLinkError.h>
+#endif
+
#define DIE(Message) die (JvNewStringLatin1 (Message))
typedef void main_func (jobject);
+#ifdef WITH_JVMPI
+extern void (*_Jv_JVMPI_Notify_THREAD_START) (JVMPI_Event *event);
+#endif
+
+/* This will be non-NULL if the user has preloaded a JNI library, or
+ linked one into the executable. */
+extern "C"
+{
+#pragma weak JNI_OnLoad
+ extern jint JNI_OnLoad (JavaVM *, void *) __attribute__((weak));
+}
+
void
gnu::gcj::runtime::FirstThread::run (void)
{
+
Utf8Const* main_signature = _Jv_makeUtf8Const ("([Ljava.lang.String;)V", 22);
Utf8Const* main_name = _Jv_makeUtf8Const ("main", 4);
+ /* Some systems let you preload shared libraries before running a
+ program. Under Linux, this is done by setting the LD_PRELOAD
+ environment variable. We take advatage of this here to allow for
+ dynamically loading a JNI library into a fully linked executable. */
+
+ if (JNI_OnLoad != NULL)
+ {
+ JavaVM *vm = _Jv_GetJavaVM ();
+ if (vm == NULL)
+ {
+ // FIXME: what?
+ return;
+ }
+ jint vers = JNI_OnLoad (vm, NULL);
+ if (vers != JNI_VERSION_1_1 && vers != JNI_VERSION_1_2)
+ {
+ // FIXME: unload the library.
+ _Jv_Throw (new java::lang::UnsatisfiedLinkError (JvNewStringLatin1 ("unrecognized version from preloaded JNI_OnLoad")));
+ }
+ }
+
if (klass == NULL)
{
klass = java::lang::Class::forName (klass_name);
@@ -48,6 +89,60 @@ gnu::gcj::runtime::FirstThread::run (void)
if (! java::lang::reflect::Modifier::isPublic(meth->accflags))
DIE ("`main' must be public");
+#ifdef WITH_JVMPI
+ if (_Jv_JVMPI_Notify_THREAD_START)
+ {
+ JVMPI_Event event;
+
+ jstring thread_name = getName ();
+ jstring group_name = NULL, parent_name = NULL;
+ java::lang::ThreadGroup *group = getThreadGroup ();
+
+ if (group)
+ {
+ group_name = group->getName ();
+ group = group->getParent ();
+
+ if (group)
+ parent_name = group->getName ();
+ }
+
+ int thread_len = thread_name ? JvGetStringUTFLength (thread_name) : 0;
+ int group_len = group_name ? JvGetStringUTFLength (group_name) : 0;
+ int parent_len = parent_name ? JvGetStringUTFLength (parent_name) : 0;
+
+ char thread_chars[thread_len + 1];
+ char group_chars[group_len + 1];
+ char parent_chars[parent_len + 1];
+
+ if (thread_name)
+ JvGetStringUTFRegion (thread_name, 0,
+ thread_name->length(), thread_chars);
+ if (group_name)
+ JvGetStringUTFRegion (group_name, 0,
+ group_name->length(), group_chars);
+ if (parent_name)
+ JvGetStringUTFRegion (parent_name, 0,
+ parent_name->length(), parent_chars);
+
+ thread_chars[thread_len] = '\0';
+ group_chars[group_len] = '\0';
+ parent_chars[parent_len] = '\0';
+
+ event.event_type = JVMPI_EVENT_THREAD_START;
+ event.env_id = NULL;
+ event.u.thread_start.thread_name = thread_chars;
+ event.u.thread_start.group_name = group_chars;
+ event.u.thread_start.parent_name = parent_chars;
+ event.u.thread_start.thread_id = (jobjectID) this;
+ event.u.thread_start.thread_env_id = _Jv_GetCurrentJNIEnv ();
+
+ _Jv_DisableGC ();
+ (*_Jv_JVMPI_Notify_THREAD_START) (&event);
+ _Jv_EnableGC ();
+ }
+#endif
+
main_func *real_main = (main_func *) meth->ncode;
(*real_main) (args);
}