* src/native/jni.c (jni_init_localref_table): New function.
authortwisti <none@none>
Thu, 5 Oct 2006 14:13:06 +0000 (14:13 +0000)
committertwisti <none@none>
Thu, 5 Oct 2006 14:13:06 +0000 (14:13 +0000)
(AttachCurrentThread): Implemented.
(JNI_CreateJavaVM): Use jni_init_localref_table.

* src/threads/native/threads.c (method_thread_init)
(method_threadgroup_add): New global variables.
(threads_init): Store methods resolved in global variables.
(threads_attach_current_thread): New function.

* src/threads/native/threads.h (MIN_PRIORITY, NORM_PRIORITY)
(MAX_PRIORITY): Defined.
(threads_attach_current_thread): New function.

src/native/jni.c
src/threads/native/threads.c
src/threads/native/threads.h

index aec7fc65848f3b42c2753c306967c6d9f7d08f4a..ecc2a6e5f8ab3b85d874a465f34bd8598ef70e30 100644 (file)
@@ -32,7 +32,7 @@
             Christian Thalinger
                        Edwin Steiner
 
-   $Id: jni.c 5616 2006-10-01 22:55:49Z twisti $
+   $Id: jni.c 5691 2006-10-05 14:13:06Z twisti $
 
 */
 
@@ -205,6 +205,36 @@ bool jni_init(void)
 }
 
 
+/* jni_init_localref_table *****************************************************
+
+   Initializes the local references table of the current thread.
+
+*******************************************************************************/
+
+static bool jni_init_localref_table(void)
+{
+       localref_table *lrt;
+
+       lrt = GCNEW(localref_table);
+
+       if (lrt == NULL)
+               return false;
+
+       lrt->capacity    = LOCALREFTABLE_CAPACITY;
+       lrt->used        = 0;
+       lrt->localframes = 1;
+       lrt->prev        = LOCALREFTABLE;
+
+       /* clear the references array (memset is faster then a for-loop) */
+
+       MSET(lrt->refs, 0, java_objectheader*, LOCALREFTABLE_CAPACITY);
+
+       LOCALREFTABLE = lrt;
+
+       return true;
+}
+
+
 /* _Jv_jni_vmargs_from_objectarray *********************************************
 
    XXX
@@ -5510,18 +5540,55 @@ jint _Jv_JNI_DestroyJavaVM(JavaVM *vm)
 
 *******************************************************************************/
 
-jint _Jv_JNI_AttachCurrentThread(JavaVM *vm, void **env, void *thr_args)
+jint _Jv_JNI_AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args)
 {
+       JavaVMAttachArgs *vm_aargs;
+
        STATISTICS(jniinvokation());
 
-       log_text("JNI-Call: AttachCurrentThread: IMPLEMENT ME!");
+       log_text("JNI-Call: AttachCurrentThread");
 
-       *env = _Jv_env;
+#if defined(ENABLE_THREADS)
+       if (threads_get_current_threadobject() == NULL) {
+               vm_aargs = (JavaVMAttachArgs *) thr_args;
 
-       return 0;
+               if (vm_aargs != NULL) {
+                       if ((vm_aargs->version != JNI_VERSION_1_2) &&
+                               (vm_aargs->version != JNI_VERSION_1_4))
+                               return JNI_EVERSION;
+               }
+
+               if (!threads_attach_current_thread(vm_aargs, false))
+                       return JNI_ERR;
+
+               if (!jni_init_localref_table())
+                       return JNI_ERR;
+       }
+#endif
+
+       *p_env = _Jv_env;
+
+       return JNI_OK;
 }
 
 
+/* DetachCurrentThread *********************************************************
+
+   Detaches the current thread from a Java VM. All Java monitors held
+   by this thread are released. All Java threads waiting for this
+   thread to die are notified.
+
+   In JDK 1.1, the main thread cannot be detached from the VM. It must
+   call DestroyJavaVM to unload the entire VM.
+
+   In the JDK, the main thread can be detached from the VM.
+
+   The main thread, which is the thread that created the Java VM,
+   cannot be detached from the VM. Instead, the main thread must call
+   JNI_DestroyJavaVM() to unload the entire VM.
+
+*******************************************************************************/
+
 jint _Jv_JNI_DetachCurrentThread(JavaVM *vm)
 {
        STATISTICS(jniinvokation());
@@ -5583,8 +5650,20 @@ jint _Jv_JNI_GetEnv(JavaVM *vm, void **env, jint version)
 }
 
 
+/* AttachCurrentThreadAsDaemon *************************************************
 
-jint _Jv_JNI_AttachCurrentThreadAsDaemon(JavaVM *vm, void **par1, void *par2)
+   Same semantics as AttachCurrentThread, but the newly-created
+   java.lang.Thread instance is a daemon.
+
+   If the thread has already been attached via either
+   AttachCurrentThread or AttachCurrentThreadAsDaemon, this routine
+   simply sets the value pointed to by penv to the JNIEnv of the
+   current thread. In this case neither AttachCurrentThread nor this
+   routine have any effect on the daemon status of the thread.
+
+*******************************************************************************/
+
+jint _Jv_JNI_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *args)
 {
        STATISTICS(jniinvokation());
 
@@ -5947,7 +6026,6 @@ jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
        JavaVMInitArgs *_vm_args;
        _Jv_JNIEnv     *env;
        _Jv_JavaVM     *vm;
-       localref_table *lrt;
 
        /* get the arguments for the new JVM */
 
@@ -5974,36 +6052,28 @@ jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
 
        /* actually create the JVM */
 
-       if (!vm_create(_vm_args)) {
-               /* release allocated memory */
-
-               FREE(env, _Jv_JNIEnv);
-               FREE(vm, _Jv_JavaVM);
-
-               return -1;
-       }
+       if (!vm_create(_vm_args))
+               goto error;
 
        /* setup the local ref table (must be created after vm_create) */
 
-       lrt = GCNEW(localref_table);
-
-       lrt->capacity    = LOCALREFTABLE_CAPACITY;
-       lrt->used        = 0;
-       lrt->localframes = 1;
-       lrt->prev        = LOCALREFTABLE;
-
-       /* clear the references array (memset is faster then a for-loop) */
-
-       MSET(lrt->refs, 0, java_objectheader*, LOCALREFTABLE_CAPACITY);
-
-       LOCALREFTABLE = lrt;
+       if (!jni_init_localref_table())
+               goto error;
 
        /* now return the values */
 
        *p_vm  = (JavaVM *) vm;
        *p_env = (void *) env;
 
-       return 0;
+       return JNI_OK;
+
+ error:
+       /* release allocated memory */
+
+       FREE(env, _Jv_JNIEnv);
+       FREE(vm, _Jv_JavaVM);
+
+       return JNI_ERR;
 }
 
 
index a9925e60b318ec5e127d37e86726cdfa1badcf50..7400fc0438487da5a13537e722871ea7ecdf207a 100644 (file)
@@ -29,7 +29,7 @@
    Changes: Christian Thalinger
                        Edwin Steiner
 
-   $Id: threads.c 5590 2006-09-30 13:51:12Z michi $
+   $Id: threads.c 5691 2006-10-05 14:13:06Z twisti $
 
 */
 
@@ -212,6 +212,9 @@ static void threads_table_dump(FILE *file);
 /* the main thread                                                            */
 threadobject *mainthreadobj;
 
+methodinfo *method_thread_init;
+methodinfo *method_threadgroup_add;
+
 /* the thread object of the current thread                                    */
 /* This is either a thread-local variable defined with __thread, or           */
 /* a thread-specific value stored with key threads_current_threadobject_key.  */
@@ -735,7 +738,6 @@ bool threads_init(void)
        java_lang_Thread      *mainthread;
        java_lang_ThreadGroup *threadgroup;
        threadobject          *tempthread;
-       methodinfo            *method;
 
        tempthread = mainthreadobj;
 
@@ -803,17 +805,18 @@ bool threads_init(void)
 
        /* call Thread.<init>(Ljava/lang/VMThread;Ljava/lang/String;IZ)V */
 
-       method = class_resolveclassmethod(class_java_lang_Thread,
-                                                                         utf_init,
-                                                                         utf_new_char("(Ljava/lang/VMThread;Ljava/lang/String;IZ)V"),
-                                                                         class_java_lang_Thread,
-                                                                         true);
+       method_thread_init =
+               class_resolveclassmethod(class_java_lang_Thread,
+                                                                utf_init,
+                                                                utf_new_char("(Ljava/lang/VMThread;Ljava/lang/String;IZ)V"),
+                                                                class_java_lang_Thread,
+                                                                true);
 
-       if (method == NULL)
+       if (method_thread_init == NULL)
                return false;
 
-       (void) vm_call_method(method, (java_objectheader *) mainthread,
-                                                 mainthreadobj, threadname, 5, false);
+       (void) vm_call_method(method_thread_init, (java_objectheader *) mainthread,
+                                                 mainthreadobj, threadname, NORM_PRIORITY, false);
 
        if (*exceptionptr)
                return false;
@@ -822,22 +825,24 @@ bool threads_init(void)
 
        /* add mainthread to ThreadGroup */
 
-       method = class_resolveclassmethod(class_java_lang_ThreadGroup,
-                                                                         utf_new_char("addThread"),
-                                                                         utf_new_char("(Ljava/lang/Thread;)V"),
-                                                                         class_java_lang_ThreadGroup,
-                                                                         true);
+       method_threadgroup_add =
+               class_resolveclassmethod(class_java_lang_ThreadGroup,
+                                                                utf_new_char("addThread"),
+                                                                utf_new_char("(Ljava/lang/Thread;)V"),
+                                                                class_java_lang_ThreadGroup,
+                                                                true);
 
-       if (method == NULL)
+       if (method_threadgroup_add == NULL)
                return false;
 
-       (void) vm_call_method(method, (java_objectheader *) threadgroup,
+       (void) vm_call_method(method_threadgroup_add, 
+                                                 (java_objectheader *) threadgroup,
                                                  mainthread);
 
        if (*exceptionptr)
                return false;
 
-       threads_set_thread_priority(pthread_self(), 5);
+       threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
 
        /* initialize the thread attribute object */
 
@@ -1246,6 +1251,97 @@ void threads_start_thread(java_lang_Thread *t, functionptr function)
 }
 
 
+/* threads_attach_current_thread ***********************************************
+
+   Attaches the current thread to the VM.  Required in JNI.
+
+*******************************************************************************/
+
+bool threads_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
+{
+       threadobject          *t;
+       java_lang_Thread      *thread;
+       utf                   *u;
+       java_lang_String      *s;
+       char                  *name;
+       java_lang_ThreadGroup *group;
+
+       /* create a java.lang.VMThread object */
+
+       t = (threadobject *) builtin_new(class_java_lang_VMThread);
+
+       if (t == NULL)
+               return false;
+
+       threads_init_threadobject(&t->o);
+       threads_set_current_threadobject(t);
+       lock_init_execution_env(t);
+
+       /* insert the thread into the threadlist and the threads table */
+
+       pthread_mutex_lock(&threadlistlock);
+
+       t->prev             = mainthreadobj;
+       t->next             = mainthreadobj->next;
+       mainthreadobj->next = t;
+       t->next->prev       = t;
+
+       threads_table_add(t);
+
+       pthread_mutex_unlock(&threadlistlock);
+
+       /* mark main thread as Java thread */
+
+       t->flags = THREAD_FLAG_JAVA;
+
+#if defined(ENABLE_INTRP)
+       /* create interpreter stack */
+
+       if (opt_intrp) {
+               MSET(intrp_main_stack, 0, u1, opt_stacksize);
+               t->_global_sp = intrp_main_stack + opt_stacksize;
+       }
+#endif
+
+       /* create a java.lang.Thread object */
+
+       thread = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
+
+       if (thread == NULL)
+               return false;
+
+       t->o.thread = thread;
+
+       if (vm_aargs != NULL) {
+               u     = utf_new_char(vm_aargs->name);
+               group = (java_lang_ThreadGroup *) vm_aargs->group;
+       }
+       else {
+               u     = utf_null;
+               group = mainthreadobj->o.thread->group;
+       }
+
+       s = javastring_new(u);
+
+       (void) vm_call_method(method_thread_init, (java_objectheader *) thread, t,
+                                                 s, NORM_PRIORITY, isdaemon);
+
+       if (*exceptionptr)
+               return false;
+
+       /* store the thread group in the object */
+
+       thread->group = group;
+
+       (void) vm_call_method(method_threadgroup_add, group, thread);
+
+       if (*exceptionptr)
+               return false;
+
+       return true;
+}
+
+
 /* threads_find_non_daemon_thread **********************************************
 
    Helper function used by threads_join_all_threads for finding
index 9278244d8fab69058b11b8b56158fdb51b406939..c74ca6e3892e2e66e0ab0e81d09c4d10468ec02f 100644 (file)
@@ -29,7 +29,7 @@
 
    Changes: Christian Thalinger
 
-   $Id: threads.h 5049 2006-06-23 12:07:26Z twisti $
+   $Id: threads.h 5691 2006-10-05 14:13:06Z twisti $
 
 */
 
@@ -80,6 +80,13 @@ typedef union  threads_table_entry_t threads_table_entry_t;
 typedef struct threads_table_t       threads_table_t;
 
 
+/* thread priorities **********************************************************/
+
+#define MIN_PRIORITY     1
+#define NORM_PRIORITY    5
+#define MAX_PRIORITY     10
+
+
 /* current threadobject *******************************************************/
 
 #if defined(HAVE___THREAD)
@@ -201,6 +208,8 @@ void threads_init_threadobject(java_lang_VMThread *);
 
 void threads_start_thread(java_lang_Thread *t, functionptr function);
 
+bool threads_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon);
+
 void threads_join_all_threads(void);
 
 void threads_sleep(s8 millis, s4 nanos);