costin 02/01/11 21:06:06 Modified: jk/native2/common jk_jni_worker.c Log: Jni worker, with starting the vm removed, a bit of cleanup, etc. Seems to work fine ( starting the vm, etc ) - need to get the rest working. ( and to start the real tomcats to do the work :-) Revision Changes Path 1.11 +260 -1021 jakarta-tomcat-connectors/jk/native2/common/jk_jni_worker.c Index: jk_jni_worker.c =================================================================== RCS file: /home/cvs/jakarta-tomcat-connectors/jk/native2/common/jk_jni_worker.c,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- jk_jni_worker.c 16 Dec 2001 23:18:11 -0000 1.10 +++ jk_jni_worker.c 12 Jan 2002 05:06:06 -0000 1.11 @@ -55,313 +55,110 @@ * * * ========================================================================= */ -/*************************************************************************** - * Description: In process JNI worker * - * Author: Gal Shachor <[EMAIL PROTECTED]> * - * Based on: * - * Version: $Revision: 1.10 $ * - ***************************************************************************/ - -#if !defined(WIN32) && !defined(NETWARE) -#include <dlfcn.h> -#endif - -#include <jni.h> - -#include "jk_pool.h" -#include "jk_env.h" - -#if defined LINUX && defined APACHE2_SIGHACK -#include <pthread.h> -#include <signal.h> -#include <bits/signum.h> -#endif - -#ifdef NETWARE -#include <nwthread.h> -#include <nwadv.h> -#endif -#include "jk_logger.h" -#include "jk_service.h" - -#ifndef JNI_VERSION_1_1 -#define JNI_VERSION_1_1 0x00010001 -#endif - -#define null_check(e) if ((e) == 0) return JK_FALSE - -jint (JNICALL *jni_get_default_java_vm_init_args)(void *) = NULL; -jint (JNICALL *jni_create_java_vm)(JavaVM **, JNIEnv **, void *) = NULL; -jint (JNICALL *jni_get_created_java_vms)(JavaVM **, int, int *) = NULL; - -#define JAVA_BRIDGE_CLASS_NAME ("org/apache/tomcat/modules/server/JNIEndpoint") -/* #define JAVA_BRIDGE_CLASS_NAME ("org/apache/tomcat/service/JNIEndpoint") +/** + * In process JNI worker + * @author: Gal Shachor <[EMAIL PROTECTED]> + * @author: Costin Manolache */ -static jk_worker_t *the_singleton_jni_worker = NULL; - -struct jni_worker { - - int was_verified; - int was_initialized; +#include "jk_vm.h" +#include "jk_registry.h" +#include "jni.h" - jk_pool_t *pool; +/* default only, is configurable now */ +#define JAVA_BRIDGE_CLASS_NAME ("org/apache/jk/common/ChannelJni") - /* - * JVM Object pointer. - */ - JavaVM *jvm; - - /* - * [V] JNIEnv used for boostraping from validate -> init w/o an attach - */ - JNIEnv *tmp_env; +struct jni_worker_data { - /* - * Web Server to Java bridge, instance and class. - */ - jobject jk_java_bridge_object; + jk_vm_t *vm; + jclass jk_java_bridge_class; - /* - * Java methods ids, to jump into the JVM - */ jmethodID jk_startup_method; jmethodID jk_service_method; jmethodID jk_shutdown_method; - /* - * Command line for tomcat startup - */ + char *className; char *tomcat_cmd_line; - - /* - * Classpath - */ - char *tomcat_classpath; - - /* - * Full path to the jni javai/jvm dll - */ - char *jvm_dll_path; - - /* - * Initial Java heap size - */ - unsigned tomcat_ms; - - /* - * Max Java heap size - */ - unsigned tomcat_mx; - - /* - * Java system properties - */ - char **sysprops; - -#ifdef JNI_VERSION_1_2 - /* - * Java 2 initialization options (-X... , -verbose etc.) - */ - char **java2opts; - - /* - * Java 2 lax/strict option checking (bool) - */ - int java2lax; -#endif - - /* - * stdout and stderr file names for Java - */ char *stdout_name; char *stderr_name; - - char *name; - jk_worker_t worker; }; -typedef struct jni_worker jni_worker_t; - -struct jni_endpoint { - int attached; - JNIEnv *env; - jni_worker_t *worker; - - jk_endpoint_t endpoint; -}; -typedef struct jni_endpoint jni_endpoint_t; - -int JK_METHOD jk_worker_jni_factory(jk_env_t *env, jk_pool_t *pool, - void **result, - char *type, char *name); - -static int load_jvm_dll(jk_env_t *env, jni_worker_t *p); - -static int open_jvm(jk_env_t *env, jni_worker_t *p, - JNIEnv **jniEnv); - -static int open_jvm1(jk_env_t *env, jni_worker_t *p, - JNIEnv **jniEnv); - -#ifdef JNI_VERSION_1_2 -static int detect_jvm_version(jk_env_t *env); - -static int open_jvm2(jk_env_t *env, jni_worker_t *p, - JNIEnv **jniEnv); -#endif - - -static int get_bridge_object(jk_env_t *env, jni_worker_t *p, - JNIEnv *jniEnv ); - -static int get_method_ids(jk_env_t *env, jni_worker_t *p, - JNIEnv *jniEnv); - -static JNIEnv *attach_to_jvm(jk_env_t *env, jni_worker_t *p); - -static void detach_from_jvm(jk_env_t *env, jni_worker_t *p); -static char **jk_parse_sysprops(jk_env_t *env, jk_pool_t *p, - const char *sysprops); +typedef struct jni_worker_data jni_worker_data_t; -static int jk_file_exists(jk_env_t *env, const char *f); -static void jk_append_libpath(jk_env_t *env, jk_pool_t *p, - const char *libpath); - - -#if defined LINUX && defined APACHE2_SIGHACK -static void linux_signal_hack() -{ - sigset_t newM; - sigset_t old; - - sigemptyset(&newM); - pthread_sigmask( SIG_SETMASK, &newM, &old ); - - sigdelset(&old, SIGUSR1 ); - sigdelset(&old, SIGUSR2 ); - sigdelset(&old, SIGUNUSED ); - sigdelset(&old, SIGRTMIN ); - sigdelset(&old, SIGRTMIN + 1 ); - sigdelset(&old, SIGRTMIN + 2 ); - pthread_sigmask( SIG_SETMASK, &old, NULL ); -} - -static void print_signals( sigset_t *sset) { - int sig; - for (sig = 1; sig < 20; sig++) - { if (sigismember(sset, sig)) {printf( " %d", sig);} } - printf( "\n"); -} -#endif - -static char **jk_parse_sysprops(jk_env_t *env, jk_pool_t *pool, - const char *sysprops) -{ - char **rc = NULL; - - if(pool && sysprops) { - char *prps = pool->pstrdup(env, pool, sysprops); - if(prps && strlen(prps)) { - unsigned num_of_prps; - - for(num_of_prps = 1; *sysprops ; sysprops++) { - if('*' == *sysprops) { - num_of_prps++; - } - } - - rc = pool->alloc(env, pool, (num_of_prps + 1) * sizeof(char *)); - if(rc) { - unsigned i = 0; - char *tmp = strtok(prps, "*"); - - while(tmp && i < num_of_prps) { - rc[i] = tmp; - tmp = strtok(NULL, "*"); - i++; - } - rc[i] = NULL; - } - } - } - - return rc; -} - -static int jk_file_exists(jk_env_t *env, const char *f) -{ - if(f) { - struct stat st; - if((0 == stat(f, &st)) && (st.st_mode & S_IFREG)) { - return JK_TRUE; - } - } - return JK_FALSE; -} - - -static void jk_append_libpath(jk_env_t *env, jk_pool_t *pool, - const char *libpath) +/** Static methods - much easier... + */ +static int get_method_ids(jk_env_t *env, jni_worker_data_t *p, JNIEnv *jniEnv ) { - char *envVar = NULL; - char *current = getenv(PATH_ENV_VARIABLE); - if(current) { - envVar = pool->alloc(env, pool, strlen(PATH_ENV_VARIABLE) + - strlen(current) + - strlen(libpath) + 5); - if(envVar) { - sprintf(envVar, "%s=%s%c%s", - PATH_ENV_VARIABLE, - libpath, - PATH_SEPERATOR, - current); - } - } else { - envVar = pool->alloc(env, pool, strlen(PATH_ENV_VARIABLE) + - strlen(libpath) + 5); - if(envVar) { - sprintf(envVar, "%s=%s", PATH_ENV_VARIABLE, libpath); - } + p->jk_startup_method = + (*jniEnv)->GetStaticMethodID(jniEnv, p->jk_java_bridge_class, + "startup", + "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I"); + + if(!p->jk_startup_method) { + env->l->jkLog(env, env->l, JK_LOG_EMERG, "Can't find startup()\n"); + return JK_FALSE; } - if(envVar) { - putenv(envVar); + p->jk_service_method = (*jniEnv)->GetStaticMethodID(jniEnv, + p->jk_java_bridge_class, + "service", + "(JJ)I"); + if(!p->jk_service_method) { + env->l->jkLog(env, env->l, JK_LOG_EMERG, "Can't find service()\n"); + return JK_FALSE; } + + p->jk_shutdown_method = (*jniEnv)->GetStaticMethodID(jniEnv, + p->jk_java_bridge_class, + "shutdown", + "()V"); + if(!p->jk_shutdown_method) { + env->l->jkLog(env, env->l, JK_LOG_EMERG, "Can't find shutdown()\n"); + return JK_FALSE; + } + + return JK_TRUE; } -static int JK_METHOD service(jk_env_t *env, jk_endpoint_t *e, - jk_ws_service_t *s, - int *is_recoverable_error) +static int JK_METHOD jni_worker_service(jk_env_t *env, jk_endpoint_t *e, + jk_ws_service_t *s, + int *is_recoverable_error) { - jni_endpoint_t *p; + JNIEnv *jniEnv; jint rc; - - env->l->jkLog(env, env->l, JK_LOG_DEBUG, "Into service\n"); - if(!e || !e->endpoint_private || !s) { - env->l->jkLog(env, env->l, JK_LOG_ERROR, - "jni.service() NullPointerException\n"); - return JK_FALSE; + jni_worker_data_t *jniWorker; + + if(!e || !s) { + env->l->jkLog(env, env->l, JK_LOG_ERROR, + "jni.service() NullPointerException\n"); + return JK_FALSE; } - p = e->endpoint_private; - if(!is_recoverable_error) { - return JK_FALSE; + env->l->jkLog(env, env->l, JK_LOG_INFO, + "service() unrecoverable error status\n"); + return JK_FALSE; } - if(!p->attached) { + env->l->jkLog(env, env->l, JK_LOG_INFO, "service() attaching to vm\n"); + + jniWorker=(jni_worker_data_t *)e->worker->worker_private; + + jniEnv=(JNIEnv *)e->endpoint_private; + if(jniEnv==NULL) { /*! attached */ /* Try to attach */ - if(!(p->env = attach_to_jvm(env, p->worker))) { + jniEnv = jniWorker->vm->attach(env, jniWorker->vm); + + if(jniEnv == NULL ) { env->l->jkLog(env, env->l, JK_LOG_ERROR, "Attach failed\n"); /* Is it recoverable ?? */ *is_recoverable_error = JK_TRUE; return JK_FALSE; } - p->attached = JK_TRUE; + e->endpoint_private = jniEnv; } /* we are attached now */ @@ -375,60 +172,59 @@ env->l->jkLog(env, env->l, JK_LOG_INFO, "jni.service() calling Tomcat...\n"); - rc = (*(p->env))->CallIntMethod(p->env, - p->worker->jk_java_bridge_object, - p->worker->jk_service_method, - /* [V] For some reason gcc likes this pointer -> int -> jlong conversion, */ - /* but not the direct pointer -> jlong conversion. I hope it's okay. */ - (jlong)(int)s, - (jlong)(int)env); + /* [V] For some reason gcc likes this pointer -> int -> jlong + conversion, but not the direct pointer -> jlong conversion. + I hope it's okay. */ + rc = (*jniEnv)->CallStaticIntMethod( jniEnv, + jniWorker->jk_java_bridge_class, + jniWorker->jk_service_method, + (jlong)(int)s, + (jlong)(int)env); /* [V] Righ now JNIEndpoint::service() only returns 1 or 0 */ if(rc) { - env->l->jkLog(env, env->l, JK_LOG_DEBUG, - "In service, Tomcat returned OK, done\n"); + env->l->jkLog(env, env->l, JK_LOG_INFO, + "service() Tomcat returned OK, done\n"); return JK_TRUE; } else { - env->l->jkLog(env, env->l, JK_LOG_ERROR, - "In service, Tomcat FAILED!\n"); + env->l->jkLog(env, env->l, JK_LOG_INFO, + "service() Tomcat FAILED!\n"); return JK_FALSE; } } -static int JK_METHOD done(jk_env_t *env, jk_endpoint_t *e) +static int JK_METHOD jni_worker_done(jk_env_t *env, jk_endpoint_t *e) { - jni_endpoint_t *p; - - if(e==NULL || e->endpoint_private==NULL) { + jni_worker_data_t *jniWorker; + + if(e==NULL) { env->l->jkLog(env, env->l, JK_LOG_ERROR, "jni.done() NullPointerException\n"); return JK_FALSE; } - env->l->jkLog(env, env->l, JK_LOG_DEBUG, - "jni.done()\n"); + jniWorker=(jni_worker_data_t *)e->worker->worker_private; + + /* XXX Don't detach if worker is reused per thread */ + e->endpoint_private=NULL; + jniWorker->vm->detach( env, jniWorker->vm ); - p = e->endpoint_private; - - if(p->attached) { - detach_from_jvm(env, p->worker); - } - e->pool->close( env, e->pool ); env->l->jkLog(env, env->l, JK_LOG_INFO, "jni.done() ok\n"); return JK_TRUE; } -static int JK_METHOD validate(jk_env_t *env, jk_worker_t *pThis, - jk_map_t *props, jk_workerEnv_t *we) + +static int JK_METHOD jni_worker_validate(jk_env_t *env, jk_worker_t *pThis, + jk_map_t *props, jk_workerEnv_t *we) { - jni_worker_t *p; + jni_worker_data_t *jniWorker; int mem_config = 0; char *str_config = NULL; + int rc; JNIEnv *jniEnv; - - env->l->jkLog(env, env->l, JK_LOG_DEBUG, "Into validate\n"); + char *prefix; if(! pThis || ! pThis->worker_private) { env->l->jkLog(env, env->l, JK_LOG_ERROR, @@ -436,136 +232,99 @@ return JK_FALSE; } - p = pThis->worker_private; + jniWorker = pThis->worker_private; - if(p->was_verified) { - env->l->jkLog(env, env->l, JK_LOG_DEBUG, - "validate, been here before, done\n"); - return JK_TRUE; - } - - mem_config= jk_map_getIntProp( env, props, "worker", p->name, "mx", -1 ); - if( mem_config != -1 ) { - p->tomcat_mx = mem_config; - } - - mem_config= jk_map_getIntProp( env, props, "worker", p->name, "ms", -1 ); - if(mem_config != -1 ) { - p->tomcat_ms = mem_config; - } - - str_config= jk_map_getStrProp( env, props, "worker", p->name, - "class_path", NULL ); - if(str_config != NULL ) { - p->tomcat_classpath = p->pool->pstrdup(env, p->pool, str_config); - } - - if(!p->tomcat_classpath) { - env->l->jkLog(env, env->l, JK_LOG_EMERG, "Fail-> no classpath\n"); - return JK_FALSE; - } - - str_config= jk_map_getStrProp( env, props, "worker", p->name, "jvm_lib", - NULL ); - if(str_config != NULL ) { - p->jvm_dll_path = p->pool->pstrdup(env, p->pool, str_config); - } - - if(!p->jvm_dll_path || !jk_file_exists(env, p->jvm_dll_path)) { - env->l->jkLog(env, env->l, JK_LOG_DEBUG, - "Fail-> no jvm_dll_path\n"); + prefix=(char *)props->pool->alloc( env, props->pool, + strlen( pThis->name ) + 10 ); + strcpy( prefix, "worker." ); + strcat( prefix, pThis->name ); + fprintf(stderr, "Prefix= %s\n", prefix ); + + rc=jniWorker->vm->init(env, jniWorker->vm, props, prefix ); + if( rc!=JK_TRUE ) { + env->l->jkLog(env, env->l, JK_LOG_ERROR, + "jni.validate() failed to load vm init params\n"); return JK_FALSE; } + + jniWorker->className = jk_map_getStrProp( env, props, "worker", + pThis->name, + "class", JAVA_BRIDGE_CLASS_NAME); - str_config= jk_map_getStrProp( env, props, "worker", p->name, - "cmd_line", NULL ); - if(str_config != NULL ) { - p->tomcat_cmd_line = p->pool->pstrdup(env, p->pool, str_config); - } - - str_config= jk_map_getStrProp( env, props, "worker", p->name, "stdout", - NULL ); - if(str_config!= NULL ) { - p->stdout_name = p->pool->pstrdup(env, p->pool, str_config); - } - - str_config= jk_map_getStrProp( env, props, "worker", p->name, "stderr", - NULL ); - if(str_config!= NULL ) { - p->stderr_name = p->pool->pstrdup(env, p->pool, str_config); - } - - str_config= jk_map_getStrProp( env, props, "worker", p->name, - "sysprops", NULL ); - if(str_config!= NULL ) { - p->sysprops = jk_parse_sysprops(env, p->pool, str_config); - } - -#ifdef JNI_VERSION_1_2 - str_config= jk_map_getStrProp( env, props, "worker", p->name, "java2opts", - NULL ); - if( str_config != NULL ) { - /* l->jkLog(l, JK_LOG_DEBUG, "Got opts: %s\n", str_config); */ - p->java2opts = jk_parse_sysprops(env, p->pool, str_config); - } - mem_config= jk_map_getIntProp( env, props, "worker", p->name, - "java2lax", -1 ); - if(mem_config != -1 ) { - p->java2lax = mem_config ? JK_TRUE : JK_FALSE; - } -#endif - - str_config= jk_map_getStrProp( env, props, "worker", p->name, - "ld_path", NULL ); - if(str_config!= NULL ) { - jk_append_libpath(env, p->pool, str_config); - } + jniWorker->tomcat_cmd_line = jk_map_getStrProp( env, props, "worker", + pThis->name, + "cmd_line", NULL ); - if(!load_jvm_dll(env, p)) { + jniWorker->stdout_name= jk_map_getStrProp( env, props, "worker", + pThis->name, "stdout", NULL ); + jniWorker->stderr_name= jk_map_getStrProp( env, props, "worker", + pThis->name, "stderr", NULL ); + + env->l->jkLog(env, env->l, JK_LOG_INFO, + "jni.validate() cmd: %s %s %s %s\n", + jniWorker->className, jniWorker->tomcat_cmd_line, + jniWorker->stdout_name, jniWorker->stderr_name); + + /* Verify if we can load the vm XXX do we want this now ? */ + + rc= jniWorker->vm->load(env, jniWorker->vm ); + + if( !rc ) { env->l->jkLog(env, env->l, JK_LOG_EMERG, - "Fail-> can't load jvm dll\n"); + "jni.validated() Error - can't load jvm dll\n"); /* [V] no detach needed here */ return JK_FALSE; } - if(!open_jvm(env, p, &jniEnv)) { + rc = jniWorker->vm->open(env, jniWorker->vm ); + + if( rc== JK_FALSE ) { env->l->jkLog(env, env->l, JK_LOG_EMERG, "Fail-> can't open jvm\n"); /* [V] no detach needed here */ return JK_FALSE; } - if(!get_bridge_object(env, p, jniEnv)) { + jniEnv = (JNIEnv *)jniWorker->vm->attach( env, jniWorker->vm ); + + jniWorker->jk_java_bridge_class = + (*jniEnv)->FindClass(jniEnv, jniWorker->className ); + + if( jniWorker->jk_java_bridge_class == NULL ) { env->l->jkLog(env, env->l, JK_LOG_EMERG, - "Fail-> can't get bridge object\n"); + "Can't find class %s\n", str_config); /* [V] the detach here may segfault on 1.1 JVM... */ - detach_from_jvm(env, p); + jniWorker->vm->detach(env, jniWorker->vm); return JK_FALSE; } + + env->l->jkLog(env, env->l, JK_LOG_EMERG, + "Loaded %s\n", jniWorker->className); - if(!get_method_ids(env, p, jniEnv)) { + rc=get_method_ids(env, jniWorker, jniEnv); + if( !rc ) { env->l->jkLog(env, env->l, JK_LOG_EMERG, "Fail-> can't get method ids\n"); /* [V] the detach here may segfault on 1.1 JVM... */ - detach_from_jvm(env, p); + jniWorker->vm->detach(env, jniWorker->vm); return JK_FALSE; } - p->was_verified = JK_TRUE; - p->tmp_env = jniEnv; - - env->l->jkLog(env, env->l, JK_LOG_DEBUG, - "Done validate\n"); + env->l->jkLog(env, env->l, JK_LOG_INFO, + "jni.validate() ok\n"); return JK_TRUE; } -static int JK_METHOD init(jk_env_t *env, jk_worker_t *pThis, +static int JK_METHOD jni_worker_init(jk_env_t *env, jk_worker_t *pThis, jk_map_t *props, jk_workerEnv_t *we) { - jni_worker_t *p; + jni_worker_data_t *jniWorker; JNIEnv *jniEnv; - - env->l->jkLog(env, env->l, JK_LOG_DEBUG, "Into init\n"); + jstring cmd_line = NULL; + jstring stdout_name = NULL; + jstring stderr_name = NULL; + jint rc = 0; + if(! pThis || ! pThis->worker_private) { env->l->jkLog(env, env->l, JK_LOG_EMERG, @@ -573,87 +332,78 @@ return JK_FALSE; } - p = pThis->worker_private; + jniWorker = pThis->worker_private; - if(p->was_initialized) { + if(pThis->workerEnv->vm != NULL ) { env->l->jkLog(env, env->l, JK_LOG_DEBUG, - "init, done (been here!)\n"); + "jni.init(), done (been here!)\n"); return JK_TRUE; } - if(!p->jvm || - !p->jk_java_bridge_object || - !p->jk_service_method || - !p->jk_startup_method || - !p->jk_shutdown_method) { + if(!jniWorker->vm || + !jniWorker->jk_service_method || + !jniWorker->jk_startup_method || + !jniWorker->jk_shutdown_method) { env->l->jkLog(env, env->l, JK_LOG_EMERG, "Fail-> worker not set completely\n"); return JK_FALSE; } - /* [V] init is called from the same thread that called validate */ - /* there is no need to attach to the JVM, just get the env */ + env->l->jkLog(env, env->l, JK_LOG_INFO, "jni.init()\n"); - /* if(env = attach_to_jvm(p,l)) { */ - if((jniEnv = p->tmp_env)) { - jstring cmd_line = NULL; - jstring stdout_name = NULL; - jstring stderr_name = NULL; - jint rc = 0; - - if(p->tomcat_cmd_line) { - cmd_line = (*jniEnv)->NewStringUTF(jniEnv, p->tomcat_cmd_line); - } - if(p->stdout_name) { - stdout_name = (*jniEnv)->NewStringUTF(jniEnv, p->stdout_name); - } - if(p->stdout_name) { - stderr_name = (*jniEnv)->NewStringUTF(jniEnv, p->stderr_name); - } + jniEnv=jniWorker->vm->attach(env, jniWorker->vm ); + if(jniEnv == NULL) { + env->l->jkLog(env, env->l, JK_LOG_ERROR, + "jni.init() can't attach to vm\n"); + return JK_FALSE; + } - env->l->jkLog(env, env->l, JK_LOG_DEBUG, - "In init, calling Tomcat to intialize itself...\n"); + if(jniWorker->tomcat_cmd_line) { + cmd_line = (*jniEnv)->NewStringUTF(jniEnv, jniWorker->tomcat_cmd_line); + } + if(jniWorker->stdout_name) { + stdout_name = (*jniEnv)->NewStringUTF(jniEnv, jniWorker->stdout_name); + } + if(jniWorker->stdout_name) { + stderr_name = (*jniEnv)->NewStringUTF(jniEnv, jniWorker->stderr_name); + } + + env->l->jkLog(env, env->l, JK_LOG_INFO, + "jni.init() calling Tomcat to intialize itself...\n"); + + rc = (*jniEnv)->CallStaticIntMethod(jniEnv, + jniWorker->jk_java_bridge_class, + jniWorker->jk_startup_method, + cmd_line, + stdout_name, + stderr_name); + + jniWorker->vm->detach(env, jniWorker->vm); - rc = (*jniEnv)->CallIntMethod(jniEnv, - p->jk_java_bridge_object, - p->jk_startup_method, - cmd_line, - stdout_name, - stderr_name); + pThis->workerEnv->vm= jniWorker->vm; - detach_from_jvm(env, p); - - if(rc) { - p->was_initialized = JK_TRUE; - env->l->jkLog(env, env->l, JK_LOG_DEBUG, - "In init, Tomcat initialized OK, done\n"); - return JK_TRUE; - } else { - env->l->jkLog(env, env->l, JK_LOG_EMERG, - "Fail-> could not initialize Tomcat\n"); - return JK_FALSE; - } + if(rc) { + env->l->jkLog(env, env->l, JK_LOG_INFO, + "jni.init() Tomcat initialized OK, done\n"); + return JK_TRUE; } else { - env->l->jkLog(env, env->l, JK_LOG_ERROR, - "In init, FIXME: init didn't gen env from validate!\n"); + env->l->jkLog(env, env->l, JK_LOG_EMERG, + "Fail-> could not initialize Tomcat\n"); return JK_FALSE; } } -static int JK_METHOD get_endpoint(jk_env_t *env, jk_worker_t *pThis, - jk_endpoint_t **pend) +static int JK_METHOD jni_worker_getEndpoint(jk_env_t *env, jk_worker_t *pThis, + jk_endpoint_t **pend) { /* [V] This slow, needs replacement */ jk_pool_t *endpointPool; - jni_endpoint_t *e; + jk_endpoint_t *e; endpointPool=pThis->pool->create( env, pThis->pool, HUGE_POOL_SIZE ); - e = (jni_endpoint_t *)endpointPool->calloc(env, endpointPool, - sizeof(jni_endpoint_t)); - - env->l->jkLog(env, env->l, JK_LOG_DEBUG, - "Into get_endpoint\n"); + e = (jk_endpoint_t *)endpointPool->calloc(env, endpointPool, + sizeof(jk_endpoint_t)); if(!pThis || ! pThis->worker_private || !pend) { env->l->jkLog(env, env->l, JK_LOG_EMERG, @@ -667,625 +417,114 @@ return JK_FALSE; } + env->l->jkLog(env, env->l, JK_LOG_INFO, "jni.get_endpoint()\n"); /** XXX Fix the spaghetti */ - e->attached = JK_FALSE; - e->env = NULL; - e->worker = pThis->worker_private; - e->endpoint.endpoint_private = e; - e->endpoint.service = service; - e->endpoint.done = done; - e->endpoint.channelData = NULL; - e->endpoint.pool=endpointPool; - *pend = &e->endpoint; + + e->worker = pThis; + e->endpoint_private = NULL; + e->service = jni_worker_service; + e->done = jni_worker_done; + e->channelData = NULL; + e->pool=endpointPool; + *pend = e; return JK_TRUE; } -static int JK_METHOD destroy(jk_env_t *env, jk_worker_t *_this) +static int JK_METHOD jni_worker_destroy(jk_env_t *env, jk_worker_t *_this) { - jni_worker_t *p; + jni_worker_data_t *jniWorker; JNIEnv *jniEnv; - env->l->jkLog(env, env->l, JK_LOG_DEBUG, - "Into destroy\n"); - if(!_this || ! _this->worker_private) { env->l->jkLog(env, env->l, JK_LOG_EMERG, "In destroy, assert failed - invalid parameters\n"); return JK_FALSE; } - p = _this->worker_private; + jniWorker = _this->worker_private; - if(!p->jvm) { - env->l->jkLog(env, env->l, JK_LOG_DEBUG, + if(!jniWorker->vm) { + env->l->jkLog(env, env->l, JK_LOG_EMERG, "In destroy, JVM not intantiated\n"); return JK_FALSE; } - if(!p->jk_java_bridge_object || ! p->jk_shutdown_method) { - env->l->jkLog(env, env->l, JK_LOG_DEBUG, + if(! jniWorker->jk_shutdown_method) { + env->l->jkLog(env, env->l, JK_LOG_EMERG, "In destroy, Tomcat not intantiated\n"); return JK_FALSE; } - if((jniEnv = attach_to_jvm(env, p))) { - env->l->jkLog(env, env->l, JK_LOG_DEBUG, - "In destroy, shutting down Tomcat...\n"); - (*jniEnv)->CallVoidMethod(jniEnv, - p->jk_java_bridge_object, - p->jk_shutdown_method); - detach_from_jvm(env, p); + if((jniEnv = jniWorker->vm->attach(env, jniWorker->vm))) { + env->l->jkLog(env, env->l, JK_LOG_INFO, + "jni.destroy(), shutting down Tomcat...\n"); + (*jniEnv)->CallStaticVoidMethod(jniEnv, + jniWorker->jk_java_bridge_class, + jniWorker->jk_shutdown_method); + jniWorker->vm->detach(env, jniWorker->vm); } - p->pool->close(env, p->pool); + _this->pool->close(env, _this->pool); - env->l->jkLog(env, env->l, JK_LOG_DEBUG, "Done destroy\n"); + env->l->jkLog(env, env->l, JK_LOG_INFO, "jni.destroy() done\n"); return JK_TRUE; } -int JK_METHOD jk_worker_jni_factory(jk_env_t *env, jk_pool_t *pool, void **result, - char *type, char *name) +int JK_METHOD jk_worker_jni_factory(jk_env_t *env, jk_pool_t *pool, + void **result, + const char *type, const char *name) { - jni_worker_t *_this; - - env->l->jkLog(env, env->l, JK_LOG_DEBUG, "Into jni_worker_factory\n"); + jk_worker_t *_this; + jni_worker_data_t *jniData; - if(!name) { + if(name==NULL) { env->l->jkLog(env, env->l, JK_LOG_EMERG, - "In jni_worker_factory, assert failed - invalid parameters\n"); + "jni.factory() NullPointerException name==null\n"); return JK_FALSE; } - if(the_singleton_jni_worker) { - env->l->jkLog(env, env->l, JK_LOG_DEBUG, - "In jni_worker_factory, instance already created\n"); - *result = the_singleton_jni_worker; - return JK_TRUE; - } + /* No singleton - you can have multiple jni workers, + running different bridges or starting different programs inprocess*/ - _this = (jni_worker_t *)pool->calloc(env, pool, sizeof(jni_worker_t )); - - if(!_this) { - env->l->jkLog(env, env->l, JK_LOG_ERROR, - "In jni_worker_factory, memory allocation error\n"); - return JK_FALSE; - } - - _this->pool=pool; + _this=(jk_worker_t *)pool->calloc(env, pool, sizeof(jk_worker_t)); - _this->name = _this->pool->pstrdup(env, _this->pool, name); - - if(!_this->name) { + jniData = (jni_worker_data_t *)pool->calloc(env, pool, + sizeof(jni_worker_data_t )); + if(_this==NULL || jniData==NULL ) { env->l->jkLog(env, env->l, JK_LOG_ERROR, - "In jni_worker_factory, memory allocation error\n"); - _this->pool->close(env, _this->pool); - return JK_FALSE; - } - - _this->was_verified = JK_FALSE; - _this->was_initialized = JK_FALSE; - _this->jvm = NULL; - _this->tmp_env = NULL; - _this->jk_java_bridge_object = NULL; - _this->jk_java_bridge_class = NULL; - _this->jk_startup_method = NULL; - _this->jk_service_method = NULL; - _this->jk_shutdown_method = NULL; - _this->tomcat_cmd_line = NULL; - _this->tomcat_classpath = NULL; - _this->jvm_dll_path = NULL; - _this->tomcat_ms = 0; - _this->tomcat_mx = 0; - _this->sysprops = NULL; -#ifdef JNI_VERSION_1_2 - _this->java2opts = NULL; - _this->java2lax = JK_TRUE; -#endif - _this->stdout_name = NULL; - _this->stderr_name = NULL; - - _this->worker.worker_private = _this; - _this->worker.validate = validate; - _this->worker.init = init; - _this->worker.get_endpoint = get_endpoint; - _this->worker.destroy = destroy; - - *result = &_this->worker; - the_singleton_jni_worker = &_this->worker; - _this->worker.pool=pool; - - env->l->jkLog(env, env->l, JK_LOG_DEBUG, "Done jni_worker_factory\n"); - return JK_TRUE; -} - -static int load_jvm_dll(jk_env_t *env, jni_worker_t *p) -{ -#ifdef WIN32 - HINSTANCE hInst = LoadLibrary(p->jvm_dll_path); - if(hInst) { - (FARPROC)jni_create_java_vm = - GetProcAddress(hInst, "JNI_CreateJavaVM"); - - (FARPROC)jni_get_created_java_vms = - GetProcAddress(hInst, "JNI_GetCreatedJavaVMs"); - - (FARPROC)jni_get_default_java_vm_init_args = - GetProcAddress(hInst, "JNI_GetDefaultJavaVMInitArgs"); - - env->l->jkLog(env, env->l, JK_LOG_DEBUG, - "Loaded all JNI procs\n"); - - if(jni_create_java_vm && - jni_get_default_java_vm_init_args && - jni_get_created_java_vms) { - return JK_TRUE; - } - - FreeLibrary(hInst); - } -#elif defined(NETWARE) - int javaNlmHandle = FindNLMHandle("JVM"); - if (0 == javaNlmHandle) { - /* if we didn't get a handle, try to load java and retry getting the */ - /* handle */ - spawnlp(P_NOWAIT, "JVM.NLM", NULL); - ThreadSwitchWithDelay(); - javaNlmHandle = FindNLMHandle("JVM"); - if (0 == javaNlmHandle) - printf("Error loading Java."); - - } - if (0 != javaNlmHandle) { - jni_create_java_vm = ImportSymbol(GetNLMHandle(), "JNI_CreateJavaVM"); - jni_get_created_java_vms = ImportSymbol(GetNLMHandle(), - "JNI_GetCreatedJavaVMs"); - jni_get_default_java_vm_init_args = - ImportSymbol(GetNLMHandle(), "JNI_GetDefaultJavaVMInitArgs"); - } - if(jni_create_java_vm && - jni_get_default_java_vm_init_args && - jni_get_created_java_vms) { - return JK_TRUE; - } -#else - void *handle; - env->l->jkLog(env, env->l, JK_LOG_DEBUG, - "Into load_jvm_dll, load %s\n", p->jvm_dll_path); - - handle = dlopen(p->jvm_dll_path, RTLD_NOW | RTLD_GLOBAL); - - if(!handle) { - env->l->jkLog(env, env->l, JK_LOG_EMERG, - "Can't load native library %s : %s\n", p->jvm_dll_path, - dlerror()); - } else { - jni_create_java_vm = dlsym(handle, "JNI_CreateJavaVM"); - jni_get_default_java_vm_init_args = - dlsym(handle, "JNI_GetDefaultJavaVMInitArgs"); - jni_get_created_java_vms = dlsym(handle, "JNI_GetCreatedJavaVMs"); - - if(jni_create_java_vm && jni_get_default_java_vm_init_args - && jni_get_created_java_vms) { - env->l->jkLog(env, env->l, JK_LOG_DEBUG, - "In load_jvm_dll, symbols resolved, done\n"); - return JK_TRUE; - } - env->l->jkLog(env, env->l, JK_LOG_EMERG, - "Can't resolve JNI_CreateJavaVM or JNI_GetDefaultJavaVMInitArgs\n"); - dlclose(handle); - } -#endif - return JK_FALSE; -} - -static int open_jvm(jk_env_t *env, jni_worker_t *p, - JNIEnv **jniEnv) -{ -#ifdef JNI_VERSION_1_2 - int jvm_version = detect_jvm_version(env); - - switch(jvm_version) { - case JNI_VERSION_1_1: - return open_jvm1(env, p, jniEnv); - case JNI_VERSION_1_2: - return open_jvm2(env, p, jniEnv); - default: - return JK_FALSE; - } -#else - /* [V] Make sure this is _really_ visible */ - #warning ------------------------------------------------------- - #warning NO JAVA 2 HEADERS! SUPPORT FOR JAVA 2 FEATURES DISABLED - #warning ------------------------------------------------------- - return open_jvm1(env, p, jniEnv); -#endif -} - -static int open_jvm1(jk_env_t *env, jni_worker_t *p, - JNIEnv **jniEnv) -{ - JDK1_1InitArgs vm_args; - JNIEnv *penv = NULL; - int err; - *jniEnv = NULL; - - env->l->jkLog(env, env->l, JK_LOG_DEBUG, - "Into open_jvm1\n"); - - vm_args.version = JNI_VERSION_1_1; - - if(0 != jni_get_default_java_vm_init_args(&vm_args)) { - env->l->jkLog(env, env->l, JK_LOG_EMERG, - "Fail-> can't get default vm init args\n"); - return JK_FALSE; - } - env->l->jkLog(env, env->l, JK_LOG_DEBUG, - "In open_jvm_dll, got default jvm args\n"); - - if(vm_args.classpath) { - unsigned len = strlen(vm_args.classpath) + - strlen(p->tomcat_classpath) + - 3; - char *tmp = p->pool->alloc(env, p->pool, len); - if(tmp) { - sprintf(tmp, "%s%c%s", - p->tomcat_classpath, - PATH_SEPERATOR, - vm_args.classpath); - p->tomcat_classpath = tmp; - } else { - env->l->jkLog(env, env->l, JK_LOG_EMERG, - "Fail-> allocation error for classpath\n"); - return JK_FALSE; - } - } - vm_args.classpath = p->tomcat_classpath; - - if(p->tomcat_mx) { - vm_args.maxHeapSize = p->tomcat_mx; - } - - if(p->tomcat_ms) { - vm_args.minHeapSize = p->tomcat_ms; - } - - if(p->sysprops) { - vm_args.properties = p->sysprops; - } - - env->l->jkLog(env, env->l, JK_LOG_DEBUG, - "In open_jvm1, about to create JVM...\n"); - err=jni_create_java_vm(&(p->jvm), &penv, &vm_args); - - if (JNI_EEXIST == err) { - int vmCount; - env->l->jkLog(env, env->l, JK_LOG_DEBUG, "JVM alread instantiated." - "Trying to attach instead.\n"); - - jni_get_created_java_vms(&(p->jvm), 1, &vmCount); - if (NULL != p->jvm) - penv = attach_to_jvm(env, p); - - if (NULL != penv) - err = 0; - } - - if(err != 0) { - env->l->jkLog(env, env->l, JK_LOG_EMERG, - "Fail-> could not create JVM, code: %d \n", err); - return JK_FALSE; - } - env->l->jkLog(env, env->l, JK_LOG_DEBUG, - "In open_jvm1, JVM created, done\n"); - - *jniEnv = penv; - - return JK_TRUE; -} - -#ifdef JNI_VERSION_1_2 -static int detect_jvm_version(jk_env_t *env) -{ - JNIEnv *jniEnv = NULL; - JDK1_1InitArgs vm_args; - - env->l->jkLog(env, env->l, JK_LOG_DEBUG, - "Into detect_jvm_version\n"); - - /* [V] Idea: ask for 1.2. If the JVM is 1.1 it will return 1.1 instead */ - /* Note: asking for 1.1 won't work, 'cause 1.2 JVMs will return 1.1 */ - vm_args.version = JNI_VERSION_1_2; - - if(0 != jni_get_default_java_vm_init_args(&vm_args)) { - env->l->jkLog(env, env->l, JK_LOG_EMERG, - "Fail-> can't get default vm init args\n"); - return JK_FALSE; - } - env->l->jkLog(env, env->l, JK_LOG_DEBUG, - "In detect_jvm_version, found: %X, done\n", vm_args.version); - - return vm_args.version; -} - -static char* build_opt_str(jk_env_t *env, jk_pool_t *pool, - char* opt_name, char* opt_value ) -{ - unsigned len = strlen(opt_name) + strlen(opt_value) + 2; - - /* [V] IMHO, these should not be deallocated as long as the JVM runs */ - char *tmp = pool->alloc(env, pool, len); - - if(tmp) { - sprintf(tmp, "%s%s", opt_name, opt_value); - return tmp; - } else { - env->l->jkLog(env, env->l, JK_LOG_EMERG, - "Fail-> build_opt_str allocation error for %s\n", - opt_name); - return NULL; - } -} - -static char* build_opt_int(jk_env_t *env, jk_pool_t *pool, - char* opt_name, int opt_value ) -{ - /* [V] this should suffice even for 64-bit int */ - unsigned len = strlen(opt_name) + 20 + 2; - /* [V] IMHO, these should not be deallocated as long as the JVM runs */ - char *tmp = pool->alloc(env, pool, len); - - if(tmp) { - sprintf(tmp, "%s%d", opt_name, opt_value); - return tmp; - } else { - env->l->jkLog(env, env->l, JK_LOG_EMERG, - "Fail-> build_opt_int allocation error for %s\n", - opt_name); - return NULL; - } -} - -static int open_jvm2(jk_env_t *env, jni_worker_t *p, JNIEnv **jniEnv) -{ - JavaVMInitArgs vm_args; - JNIEnv *penv; - JavaVMOption options[100]; - int optn = 0, err; - char* tmp; - - *jniEnv = NULL; - - env->l->jkLog(env, env->l, JK_LOG_DEBUG, - "Into open_jvm2\n"); - - vm_args.version = JNI_VERSION_1_2; - vm_args.options = options; - - if(p->tomcat_classpath) { - env->l->jkLog(env, env->l, JK_LOG_DEBUG, - "In open_jvm2, setting classpath to %s\n", - p->tomcat_classpath); - tmp = build_opt_str(env, p->pool, "-Djava.class.path=", - p->tomcat_classpath); - null_check(tmp); - options[optn++].optionString = tmp; - } - - if(p->tomcat_mx) { - env->l->jkLog(env, env->l, JK_LOG_DEBUG, - "In open_jvm2, setting max heap to %d\n", p->tomcat_mx); - tmp = build_opt_int(env, p->pool, "-Xmx", p->tomcat_mx); - null_check(tmp); - options[optn++].optionString = tmp; - } - - if(p->tomcat_ms) { - env->l->jkLog(env, env->l, JK_LOG_DEBUG, - "In open_jvm2, setting start heap to %d\n", p->tomcat_ms); - tmp = build_opt_int(env, p->pool, "-Xms", p->tomcat_ms); - null_check(tmp); - options[optn++].optionString = tmp; - } - - if(p->sysprops) { - int i = 0; - while(p->sysprops[i]) { - env->l->jkLog(env, env->l, JK_LOG_DEBUG, - "In open_jvm2, setting %s\n", p->sysprops[i]); - tmp = build_opt_str(env, p->pool, "-D", p->sysprops[i]); - null_check(tmp); - options[optn++].optionString = tmp; - i++; - } - } - - if(p->java2opts) { - int i=0; - - while(p->java2opts[i]) { - env->l->jkLog(env, env->l, JK_LOG_DEBUG, - "In open_jvm2, using option: %s\n", p->java2opts[i]); - /* Pass it "as is" */ - options[optn++].optionString = p->java2opts[i++]; - } - } - - vm_args.nOptions = optn; - - if(p->java2lax) { - env->l->jkLog(env, env->l, JK_LOG_DEBUG, - "In open_jvm2, the JVM will ignore unknown options\n"); - vm_args.ignoreUnrecognized = JNI_TRUE; - } else { - env->l->jkLog(env, env->l, JK_LOG_DEBUG, - "In open_jvm2, the JVM will FAIL if it finds unknown options\n"); - vm_args.ignoreUnrecognized = JNI_FALSE; - } - - env->l->jkLog(env, env->l, JK_LOG_DEBUG, - "In open_jvm2, about to create JVM...\n"); - - if((err=jni_create_java_vm(&(p->jvm), &penv, &vm_args)) != 0) { - env->l->jkLog(env, env->l, JK_LOG_EMERG, - "Fail-> could not create JVM, code: %d \n", err); + "jni.factory() OutOfMemoryException \n"); return JK_FALSE; } - env->l->jkLog(env, env->l, JK_LOG_DEBUG, - "In open_jvm2, JVM created, done\n"); - *jniEnv = penv; + _this->worker_private=jniData; - return JK_TRUE; -} -#endif - -static int get_bridge_object(jk_env_t *env, jni_worker_t *p, JNIEnv *jniEnv) -{ - jmethodID constructor_method_id; - - env->l->jkLog(env, env->l, JK_LOG_DEBUG, - "Into get_bridge_object\n"); - - p->jk_java_bridge_class = (*jniEnv)->FindClass(jniEnv, JAVA_BRIDGE_CLASS_NAME); - if(!p->jk_java_bridge_class) { - env->l->jkLog(env, env->l, JK_LOG_EMERG, - "Can't find class %s\n", JAVA_BRIDGE_CLASS_NAME); - return JK_FALSE; - } - env->l->jkLog(env, env->l, JK_LOG_DEBUG, - "In get_bridge_object, loaded %s bridge class\n", - JAVA_BRIDGE_CLASS_NAME); - - constructor_method_id = (*jniEnv)->GetMethodID(jniEnv, - p->jk_java_bridge_class, - "<init>", /* method name */ - "()V"); /* method sign */ - if(!constructor_method_id) { - p->jk_java_bridge_class = NULL; - env->l->jkLog(env, env->l, JK_LOG_EMERG, - "Can't find constructor\n"); - return JK_FALSE; - } - - p->jk_java_bridge_object = (*jniEnv)->NewObject(jniEnv, - p->jk_java_bridge_class, - constructor_method_id); - if(! p->jk_java_bridge_object) { - p->jk_java_bridge_class = NULL; - env->l->jkLog(env, env->l, JK_LOG_EMERG, - "Can't create new bridge object\n"); - return JK_FALSE; - } + _this->pool=pool; + _this->name = _this->pool->pstrdup(env, _this->pool, name); - p->jk_java_bridge_object = - (jobject)(*jniEnv)->NewGlobalRef(jniEnv, p->jk_java_bridge_object); + /* XXX split it in VM11 and VM12 util */ + jk_vm_factory( env, pool, &jniData->vm, "vm", "default" ); - if(! p->jk_java_bridge_object) { - env->l->jkLog(env, env->l, JK_LOG_EMERG, - "Can't create global ref to bridge object\n"); - p->jk_java_bridge_class = NULL; - p->jk_java_bridge_object = NULL; - return JK_FALSE; - } + jniData->jk_java_bridge_class = NULL; + jniData->jk_startup_method = NULL; + jniData->jk_service_method = NULL; + jniData->jk_shutdown_method = NULL; + + jniData->tomcat_cmd_line = NULL; + jniData->stdout_name = NULL; + jniData->stderr_name = NULL; + + _this->validate = jni_worker_validate; + _this->init = jni_worker_init; + _this->get_endpoint = jni_worker_getEndpoint; + _this->destroy = jni_worker_destroy; - env->l->jkLog(env, env->l, JK_LOG_DEBUG, - "In get_bridge_object, bridge built, done\n"); - return JK_TRUE; -} + *result = _this; -static int get_method_ids(jk_env_t *env, jni_worker_t *p, JNIEnv *jniEnv ) -{ - p->jk_startup_method = - (*jniEnv)->GetMethodID(jniEnv, p->jk_java_bridge_class, "startup", - "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I"); - if(!p->jk_startup_method) { - env->l->jkLog(env, env->l, JK_LOG_EMERG, "Can't find startup()\n"); - return JK_FALSE; - } + env->l->jkLog(env, env->l, JK_LOG_INFO, + "jni.worker_factory() done\n"); - p->jk_service_method = (*jniEnv)->GetMethodID(jniEnv, - p->jk_java_bridge_class, - "service", - "(JJ)I"); - if(!p->jk_service_method) { - env->l->jkLog(env, env->l, JK_LOG_EMERG, "Can't find service()\n"); - return JK_FALSE; - } - - p->jk_shutdown_method = (*jniEnv)->GetMethodID(jniEnv, - p->jk_java_bridge_class, - "shutdown", - "()V"); - if(!p->jk_shutdown_method) { - env->l->jkLog(env, env->l, JK_LOG_EMERG, "Can't find shutdown()\n"); - return JK_FALSE; - } - return JK_TRUE; } -static JNIEnv *attach_to_jvm(jk_env_t *env, jni_worker_t *p) -{ - JNIEnv *rc = NULL; - /* [V] This message is important. If there are signal mask issues, * - * the JVM usually hangs when a new thread tries to attach to it */ - env->l->jkLog(env, env->l, JK_LOG_DEBUG, - "Into attach_to_jvm\n"); - -#if defined LINUX && defined APACHE2_SIGHACK - linux_signal_hack(); -#endif - - if(0 == (*(p->jvm))->AttachCurrentThread(p->jvm, -#ifdef JNI_VERSION_1_2 - (void **) -#endif - &rc, - NULL)) { - env->l->jkLog(env, env->l, JK_LOG_DEBUG, - "In attach_to_jvm, attached ok\n"); - return rc; - } - env->l->jkLog(env, env->l, JK_LOG_ERROR, - "In attach_to_jvm, cannot attach thread to JVM.\n"); - return NULL; -} - -/* -static JNIEnv *attach_to_jvm(jni_worker_t *p) -{ - JNIEnv *rc = NULL; - -#ifdef LINUX - linux_signal_hack(); -#endif - - if(0 == (*(p->jvm))->AttachCurrentThread(p->jvm, -#ifdef JNI_VERSION_1_2 - (void **) -#endif - &rc, - NULL)) { - return rc; - } - - return NULL; -} -*/ -static void detach_from_jvm(jk_env_t *env, jni_worker_t *p) -{ - if(!p->jvm || !(*(p->jvm))) { - env->l->jkLog(env, env->l, JK_LOG_ERROR, - "In detach_from_jvm, cannot detach from NULL JVM.\n"); - } - - if(0 == (*(p->jvm))->DetachCurrentThread(p->jvm)) { - env->l->jkLog(env, env->l, JK_LOG_DEBUG, - "In detach_from_jvm, detached ok\n"); - } else { - env->l->jkLog(env, env->l, JK_LOG_ERROR, - "In detach_from_jvm, cannot detach from JVM.\n"); - } -}
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>