* src/threads/native/threads.c (threads_init) [WITH_CLASSPATH_SUN]:
authortwisti <none@none>
Mon, 20 Aug 2007 20:24:35 +0000 (20:24 +0000)
committertwisti <none@none>
Mon, 20 Aug 2007 20:24:35 +0000 (20:24 +0000)
Added code to initialize the thread.
(threads_startup_thread): Ignore the return value of
threads_detach_thread.
(threads_detach_thread) [ENABLE_JAVASE]: Implemented
UncaughtExceptionHandler stuff.

src/threads/native/threads.c

index c3280ecb61e1ca0890b83c16814b8561311cfdfe..8393fbd87fca3bae5209c5d09739c72ba1633bd0 100644 (file)
@@ -22,7 +22,7 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: threads.c 8304 2007-08-14 19:57:20Z pm $
+   $Id: threads.c 8366 2007-08-20 20:24:35Z twisti $
 
 */
 
@@ -814,13 +814,22 @@ bool threads_init(void)
                                                                 utf_new_char("(Ljava/lang/VMThread;Ljava/lang/String;IZ)V"),
                                                                 class_java_lang_Thread,
                                                                 true);
-#else
+#elif defined(WITH_CLASSPATH_SUN)
+       method_thread_init =
+               class_resolveclassmethod(class_java_lang_Thread,
+                                                                utf_init,
+                                                                utf_new_char("(Ljava/lang/String;)V"),
+                                                                class_java_lang_Thread,
+                                                                true);
+#elif defined(WITH_CLASSPATH_CLDC1_1)
        method_thread_init =
                class_resolveclassmethod(class_java_lang_Thread,
                                                                 utf_init,
                                                                 utf_new_char("(Ljava/lang/String;)V"),
                                                                 class_java_lang_Thread,
                                                                 true);
+#else
+# error unknown classpath configuration
 #endif
 
        if (method_thread_init == NULL)
@@ -884,11 +893,17 @@ bool threads_init(void)
 
 #elif defined(WITH_CLASSPATH_SUN)
 
-       /* We trick java.lang.Thread.init, which sets the priority of the
-          current thread to the parent's one. */
+       /* We trick java.lang.Thread.<init>, which sets the priority of
+          the current thread to the parent's one. */
 
        t->priority = NORM_PRIORITY;
 
+       /* Call java.lang.Thread.<init>(Ljava/lang/String;)V */
+
+       o = (java_object_t *) t;
+
+       (void) vm_call_method(method_thread_init, o, threadname);
+
 #elif defined(WITH_CLASSPATH_CLDC1_1)
 
        /* set the thread */
@@ -1135,8 +1150,9 @@ static void *threads_startup_thread(void *arg)
                jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_END);
 #endif
 
-       if (!threads_detach_thread(thread))
-               vm_abort("threads_startup_thread: threads_detach_thread failed");
+       /* We ignore the return value. */
+
+       (void) threads_detach_thread(thread);
 
        /* set ThreadMXBean variables */
 
@@ -1417,25 +1433,68 @@ bool threads_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
 
 *******************************************************************************/
 
-bool threads_detach_thread(threadobject *thread)
+bool threads_detach_thread(threadobject *t)
 {
 #if defined(ENABLE_JAVASE)
+       java_lang_Thread      *object;
        java_lang_ThreadGroup *group;
+       java_handle_t         *e;
+       java_lang_Object      *handler;
        classinfo             *c;
        methodinfo            *m;
        java_handle_t         *o;
-       java_lang_Thread      *t;
 #endif
 
-       /* XXX implement uncaught exception stuff (like JamVM does) */
+       object = t->object;
 
 #if defined(ENABLE_JAVASE)
-       /* remove thread from the thread group */
+       group = LLNI_field_direct(object, group);
+
+    /* If there's an uncaught exception, call uncaughtException on the
+       thread's exception handler, or the thread's group if this is
+       unset. */
+
+       e = exceptions_get_and_clear_exception();
 
-       group = LLNI_field_direct(thread->object, group);
+    if (e != NULL) {
+               /* We use a java_lang_Object here, as it's not trivial to
+                  build the java_lang_Thread_UncaughtExceptionHandler header
+                  file. */
+
+# if defined(WITH_CLASSPATH_GNU)
+               handler = (java_lang_Object *) LLNI_field_direct(object, exceptionHandler);
+# elif defined(WITH_CLASSPATH_SUN)
+               handler = (java_lang_Object *) LLNI_field_direct(object, uncaughtExceptionHandler);
+# endif
+
+               if (handler != NULL) {
+                       LLNI_class_get(handler, c);
+                       o = (java_handle_t *) handler;
+               }
+               else {
+                       LLNI_class_get(group, c);
+                       o = (java_handle_t *) group;
+               }
+
+               m = class_resolveclassmethod(c,
+                                                                        utf_uncaughtException,
+                                                                        utf_java_lang_Thread_java_lang_Throwable__V,
+                                                                        NULL,
+                                                                        true);
+
+               if (m == NULL)
+                       return false;
+
+               (void) vm_call_method(m, o, object, e);
+
+               if (exceptions_get_exception())
+                       return false;
+    }
 
        /* XXX TWISTI: should all threads be in a ThreadGroup? */
 
+       /* Remove thread from the thread group. */
+
        if (group != NULL) {
                LLNI_class_get(group, c);
 
@@ -1459,9 +1518,8 @@ bool threads_detach_thread(threadobject *thread)
                        return false;
 
                o = (java_handle_t *) group;
-               t = thread->object;
 
-               (void) vm_call_method(m, o, t);
+               (void) vm_call_method(m, o, object);
 
                if (exceptions_get_exception())
                        return false;
@@ -1470,12 +1528,12 @@ bool threads_detach_thread(threadobject *thread)
 
        /* thread is terminated */
 
-       threads_thread_state_terminated(thread);
+       threads_thread_state_terminated(t);
 
 #if !defined(NDEBUG)
        if (opt_verbosethreads) {
                printf("[Detaching thread ");
-               threads_thread_print_info(thread);
+               threads_thread_print_info(t);
                printf("]\n");
        }
 #endif
@@ -1488,7 +1546,7 @@ bool threads_detach_thread(threadobject *thread)
 
        /* free the vm internal thread object */
 
-       threads_thread_free(thread);
+       threads_thread_free(t);
 
        /* Signal that this thread has finished and leave the mutex. */