* src/threads/thread.cpp: Use a finalizer to remove dead threads.
[cacao.git] / src / threads / posix / thread-posix.cpp
index a68cede39cf91c405bd86f2180fd3f137c519e65..058a3bda94522821d1b4bd600e21c667137f17cb 100644 (file)
@@ -1,6 +1,6 @@
 /* src/threads/posix/thread-posix.cpp - POSIX thread functions
 
-   Copyright (C) 1996-2005, 2006, 2007, 2008, 2010
+   Copyright (C) 1996-2011
    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
@@ -459,6 +459,7 @@ void threads_impl_thread_clear(threadobject *t)
        t->index = 0;
        t->flags = 0;
        t->state = 0;
+       t->is_in_active_list = false;
 
        t->tid = 0;
 
@@ -532,47 +533,11 @@ void threads_impl_thread_reuse(threadobject *t)
 #endif
 }
 
-
-/* threads_impl_thread_free ****************************************************
-
-   Cleanup thread stuff.
-
-   IN:
-      t....the threadobject
-
-*******************************************************************************/
-
-#if 0
-/* never used */
-void threads_impl_thread_free(threadobject *t)
+void threads_impl_clear_heap_pointers(threadobject *t)
 {
-       int result;
-
-       /* Destroy the mutex and the condition. */
-
-       delete t->flc_lock;
-
-       result = pthread_cond_destroy(&(t->flc_cond));
-
-       if (result != 0)
-               os::abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
-
-       delete t->waitmutex;
-
-       result = pthread_cond_destroy(&(t->waitcond));
-
-       if (result != 0)
-               os::abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
-
-       delete t->suspendmutex;
-
-       result = pthread_cond_destroy(&(t->suspendcond));
-
-       if (result != 0)
-               os::abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
+       t->object = 0;
+       t->flc_object = 0;
 }
-#endif
-
 
 /* threads_impl_preinit ********************************************************
 
@@ -808,36 +773,14 @@ static void *threads_startup_thread(void *arg)
        /* find and run the Thread.run()V method if no other function was passed */
 
        if (function == NULL) {
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-               /* We need to start the run method of
-                  java.lang.VMThread. Since this is a final class, we can use
-                  the class object directly. */
-
-               c = class_java_lang_VMThread;
-#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
-               LLNI_class_get(object, c);
-#else
-# error unknown classpath configuration
-#endif
+               c = ThreadRuntime::get_thread_class_from_object(object);
 
                m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true);
 
                if (m == NULL)
                        vm_abort("threads_startup_thread: run() method not found in class");
 
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-
-               // We need to start the run method of java.lang.VMThread.
-               java_lang_VMThread jlvmt(jlt.get_vmThread());
-               java_handle_t* h = jlvmt.get_handle();
-
-#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
-
-               java_handle_t* h = jlt.get_handle();
-
-#else
-# error unknown classpath configuration
-#endif
+               java_handle_t *h = ThreadRuntime::get_vmthread_handle(jlt);
 
                /* Run the thread. */
 
@@ -1000,15 +943,7 @@ bool thread_detach_current_thread(void)
                   to build the java_lang_Thread_UncaughtExceptionHandler
                   header file with cacaoh. */
 
-# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-
-               java_handle_t* handler = jlt.get_exceptionHandler();
-
-# elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-
-               java_handle_t* handler = jlt.get_uncaughtExceptionHandler();
-
-# endif
+               java_handle_t *handler = ThreadRuntime::get_thread_exception_handler(jlt);
 
                classinfo*     c;
                java_handle_t* h;
@@ -1045,21 +980,7 @@ bool thread_detach_current_thread(void)
                classinfo* c;
                LLNI_class_get(group, c);
 
-# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-               methodinfo* m = class_resolveclassmethod(c,
-                                                                                                utf_removeThread,
-                                                                                                utf_java_lang_Thread__V,
-                                                                                                class_java_lang_ThreadGroup,
-                                                                                                true);
-# elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-               methodinfo* m = class_resolveclassmethod(c,
-                                                                                                utf_remove,
-                                                                                                utf_java_lang_Thread__V,
-                                                                                                class_java_lang_ThreadGroup,
-                                                                                                true);
-# else
-#  error unknown classpath configuration
-# endif
+               methodinfo *m = ThreadRuntime::get_threadgroup_remove_method(c);
 
                if (m == NULL)
                        return false;
@@ -1090,6 +1011,10 @@ bool thread_detach_current_thread(void)
        /* XXX Care about exceptions? */
        (void) lock_monitor_exit(jlt.get_handle());
 
+       t->waitmutex->lock();
+       t->tid = 0;
+       t->waitmutex->unlock();
+
        /* Enter the join-mutex before calling thread_free, so
           threads_join_all_threads gets the correct number of non-daemon
           threads. */
@@ -1105,6 +1030,9 @@ bool thread_detach_current_thread(void)
        cond_join->signal();
        threads_mutex_join_unlock();
 
+       t->suspendmutex->lock();
+       t->suspendmutex->unlock();
+
        return true;
 }
 
@@ -1137,7 +1065,8 @@ static void threads_suspend_self()
 #endif
 
        // Release the suspension mutex and wait till we are resumed.
-       thread->suspendcond->wait(thread->suspendmutex);
+       while (thread->suspend_reason != SUSPEND_REASON_NONE)
+               thread->suspendcond->wait(thread->suspendmutex);
 
 #if defined(ENABLE_GC_CACAO)
        // XXX This is propably not ok!
@@ -1157,7 +1086,7 @@ static void threads_suspend_self()
 
 /**
  * Suspend the passed thread. Execution of that thread stops until the thread
- * is explicitly resumend again.
+ * is explicitly resumed again.
  *
  * @param thread The thread to be suspended.
  * @param reason Reason for suspending the given thread.
@@ -1189,13 +1118,14 @@ bool threads_suspend_thread(threadobject *thread, int32_t reason)
        }
        else {
                // Send the suspend signal to the other thread.
+               if (!thread->tid)
+                       return false;
                if (pthread_kill(thread->tid, SIGUSR1) != 0)
                        os::abort_errno("threads_suspend_thread: pthread_kill failed");
 
                // Wait for the thread to acknowledge the suspension.
-               // XXX A possible optimization would be to not wait here, but you
-               //     better think this through twice before trying it!
-               thread->suspendcond->wait(thread->suspendmutex);
+               while (!thread->suspended)
+                       thread->suspendcond->wait(thread->suspendmutex);
        }
 
        return true;
@@ -1486,7 +1416,8 @@ void threads_thread_interrupt(threadobject *t)
 
        /* Interrupt blocking system call using a signal. */
 
-       pthread_kill(t->tid, Signal_INTERRUPT_SYSTEM_CALL);
+       if (t->tid)
+               pthread_kill(t->tid, Signal_INTERRUPT_SYSTEM_CALL);
 
        t->waitcond->signal();