jk_jni_worker.c
来自「Tomcat 4.1与WebServer集成组件的源代码包.」· C语言 代码 · 共 1,268 行 · 第 1/3 页
C
1,268 行
/* ========================================================================= * * * * The Apache Software License, Version 1.1 * * * * Copyright (c) 1999-2001 The Apache Software Foundation. * * All rights reserved. * * * * ========================================================================= * * * * Redistribution and use in source and binary forms, with or without modi- * * fication, are permitted provided that the following conditions are met: * * * * 1. Redistributions of source code must retain the above copyright notice * * notice, this list of conditions and the following disclaimer. * * * * 2. Redistributions in binary form must reproduce the above copyright * * notice, this list of conditions and the following disclaimer in the * * documentation and/or other materials provided with the distribution. * * * * 3. The end-user documentation included with the redistribution, if any, * * must include the following acknowlegement: * * * * "This product includes software developed by the Apache Software * * Foundation <http://www.apache.org/>." * * * * Alternately, this acknowlegement may appear in the software itself, if * * and wherever such third-party acknowlegements normally appear. * * * * 4. The names "The Jakarta Project", "Jk", and "Apache Software * * Foundation" must not be used to endorse or promote products derived * * from this software without prior written permission. For written * * permission, please contact <apache@apache.org>. * * * * 5. Products derived from this software may not be called "Apache" nor may * * "Apache" appear in their names without prior written permission of the * * Apache Software Foundation. * * * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES * * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * * THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY * * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * * POSSIBILITY OF SUCH DAMAGE. * * * * ========================================================================= * * * * This software consists of voluntary contributions made by many indivi- * * duals on behalf of the Apache Software Foundation. For more information * * on the Apache Software Foundation, please see <http://www.apache.org/>. * * * * ========================================================================= *//*************************************************************************** * Description: In process JNI worker * * Author: Gal Shachor <shachor@il.ibm.com> * * Based on: * * Version: $Revision: 1.23 $ * ***************************************************************************/#if !defined(WIN32) && !defined(NETWARE) && !defined(AS400)#include <dlfcn.h>#endif#include <jni.h>#include "jk_pool.h"#include "jk_jni_worker.h"#include "jk_util.h"#if defined LINUX && defined APACHE2_SIGHACK#include <pthread.h>#include <signal.h>#include <bits/signum.h>#endif#ifdef NETWARE#ifdef __NOVELL_LIBC__#include <dlfcn.h>#else#include <nwthread.h>#include <nwadv.h>#endif#endif#ifndef JNI_VERSION_1_1#define JNI_VERSION_1_1 0x00010001#endif/* probably on an older system that doesn't support RTLD_NOW or RTLD_LAZY. * The below define is a lie since we are really doing RTLD_LAZY since the * system doesn't support RTLD_NOW. */#ifndef RTLD_NOW#define RTLD_NOW 1#endif#ifndef RTLD_GLOBAL#define RTLD_GLOBAL 0#endif#define null_check(e) if ((e) == 0) return JK_FALSEjint (JNICALL *jni_get_default_java_vm_init_args)(void *) = NULL;jint (JNICALL *jni_create_java_vm)(JavaVM **, JNIEnv **, void *) = NULL;#ifdef AS400jint (JNICALL *jni_get_created_java_vms)(JavaVM **, long, long *) = NULL;#elsejint (JNICALL *jni_get_created_java_vms)(JavaVM **, int, int *) = NULL;#endif#define TC33_JAVA_BRIDGE_CLASS_NAME ("org/apache/tomcat/modules/server/JNIEndpoint")#define TC32_JAVA_BRIDGE_CLASS_NAME ("org/apache/tomcat/service/JNIEndpoint")static jk_worker_t *the_singleton_jni_worker = NULL;struct jni_worker { int was_verified; int was_initialized; jk_pool_t p; jk_pool_atom_t buf[TINY_POOL_SIZE]; /* * JVM Object pointer. */ JavaVM *jvm; /* * [V] JNIEnv used for boostraping from validate -> init w/o an attach */ JNIEnv *tmp_env; /* * Web Server to Java bridge, instance and class. */ jobject jk_java_bridge_object; 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 *tomcat_cmd_line; /* * Bridge Type, Tomcat 32/33/40/41/5 */ unsigned bridge_type; /* * 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;static int load_jvm_dll(jni_worker_t *p, jk_logger_t *l);static int open_jvm(jni_worker_t *p, JNIEnv **env, jk_logger_t *l);static int open_jvm1(jni_worker_t *p, JNIEnv **env, jk_logger_t *l);#ifdef JNI_VERSION_1_2static int detect_jvm_version(jk_logger_t *l);static int open_jvm2(jni_worker_t *p, JNIEnv **env, jk_logger_t *l);#endifstatic int get_bridge_object(jni_worker_t *p, JNIEnv *env, jk_logger_t *l);static int get_method_ids(jni_worker_t *p, JNIEnv *env, jk_logger_t *l);static JNIEnv *attach_to_jvm(jni_worker_t *p, jk_logger_t *l);static void detach_from_jvm(jni_worker_t *p, jk_logger_t *l);/* Duplicate string and convert it to ASCII on EBDIC based systems Needed for at least AS/400 and BS2000 but what about other EBDIC systems ?*/static void *strdup_ascii(jk_pool_t *p, char *s){ char * rc; rc = jk_pool_strdup(p, s);#if defined(AS400) || defined(_OSD_POSIX) jk_xlate_to_ascii(rc, strlen(rc));#endif return rc;}#if defined LINUX && defined APACHE2_SIGHACKstatic 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");}#endifstatic int JK_METHOD service(jk_endpoint_t *e, jk_ws_service_t *s, jk_logger_t *l, int *is_recoverable_error){ jni_endpoint_t *p; jint rc; jk_log(l, JK_LOG_DEBUG, "Into service\n"); if(!e || !e->endpoint_private || !s) { jk_log(l, JK_LOG_EMERG, "In service, assert failed - invalid parameters\n"); return JK_FALSE; } p = e->endpoint_private; if(!is_recoverable_error) { return JK_FALSE; } if(!p->attached) { /* Try to attach */ if(!(p->env = attach_to_jvm(p->worker, l))) { jk_log(l, JK_LOG_EMERG, "Attach failed\n"); /* Is it recoverable ?? */ *is_recoverable_error = JK_TRUE; return JK_FALSE; } p->attached = JK_TRUE; } /* we are attached now */ /* * When we call the JVM we cannot know what happens * So we can not recover !!! */ *is_recoverable_error = JK_FALSE; jk_log(l, JK_LOG_DEBUG, "In 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. */#ifdef AS400 s, l#else (jlong)(int)s, (jlong)(int)l#endif); /* [V] Righ now JNIEndpoint::service() only returns 1 or 0 */ if(rc) { jk_log(l, JK_LOG_DEBUG, "In service, Tomcat returned OK, done\n"); return JK_TRUE; } else { jk_log(l, JK_LOG_ERROR, "In service, Tomcat FAILED!\n"); return JK_FALSE; }}static int JK_METHOD done(jk_endpoint_t **e, jk_logger_t *l){ jni_endpoint_t *p; jk_log(l, JK_LOG_DEBUG, "Into done\n"); if(!e || !*e || !(*e)->endpoint_private) { jk_log(l, JK_LOG_EMERG, "In done, assert failed - invalid parameters\n"); return JK_FALSE; } p = (*e)->endpoint_private; if(p->attached) { detach_from_jvm(p->worker,l); } free(p); *e = NULL; jk_log(l, JK_LOG_DEBUG, "Done ok\n"); return JK_TRUE;}static int JK_METHOD validate(jk_worker_t *pThis, jk_map_t *props, jk_worker_env_t *we, jk_logger_t *l){ jni_worker_t *p; int mem_config = 0; int btype = 0; char *str_config = NULL; JNIEnv *env; jk_log(l, JK_LOG_DEBUG, "Into validate\n"); if(! pThis || ! pThis->worker_private) { jk_log(l, JK_LOG_EMERG, "In validate, assert failed - invalid parameters\n"); return JK_FALSE; } p = pThis->worker_private; if(p->was_verified) { jk_log(l, JK_LOG_DEBUG, "validate, been here before, done\n"); return JK_TRUE; } if(jk_get_worker_mx(props, p->name, (unsigned int *)&mem_config)) { p->tomcat_mx = mem_config; } if(jk_get_worker_ms(props, p->name, (unsigned int *)&mem_config)) { p->tomcat_ms = mem_config; } if(jk_get_worker_classpath(props, p->name, &str_config)) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?