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 + -
显示快捷键?