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 $
*/
}
+/* 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
*******************************************************************************/
-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());
}
+/* 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());
JavaVMInitArgs *_vm_args;
_Jv_JNIEnv *env;
_Jv_JavaVM *vm;
- localref_table *lrt;
/* get the arguments for the new JVM */
/* 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;
}
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 $
*/
/* 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. */
java_lang_Thread *mainthread;
java_lang_ThreadGroup *threadgroup;
threadobject *tempthread;
- methodinfo *method;
tempthread = mainthreadobj;
/* 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;
/* 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 */
}
+/* 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