⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jk_channel_jni.c

📁 Tomcat 4.1与WebServer集成组件的源代码包.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* ========================================================================= * *                                                                           * *                 The Apache Software License,  Version 1.1                 * *                                                                           * *          Copyright (c) 1999-2002 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/>.   * *                                                                           * * ========================================================================= *//** *  Channel using jni calls ( assuming in-process tomcat ). * * @author:  Gal Shachor <shachor@il.ibm.com>                            * @author: Costin Manolache */#include "jk_workerEnv.h"#include "jk_env.h"#include "jk_bean.h"#ifdef HAVE_JNI#include "jk_map.h"#include "jk_env.h"#include "jk_channel.h"#include "jk_global.h"#include <string.h>#include "jk_registry.h"#include <jni.h>/* default only, is configurable now */#define JAVA_BRIDGE_CLASS_NAME ("org/apache/jk/apr/AprImpl")#define JNI_TOMCAT_STARTED 2extern int jk_jni_status_code;/** Information specific for the socket channel */typedef struct {    jk_vm_t *vm;        char *className;    jclass jniBridge;    jmethodID writeMethod;    int status;} jk_channel_jni_private_t;typedef struct {    JNIEnv *jniEnv;    int len;    jbyteArray jarray;    char *carray;    int arrayLen;        jobject jniJavaContext;/*     jobject msgJ; */} jk_ch_jni_ep_private_t;/*   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_env_t *env,                           char *s){#if defined(AS400) || defined(_OSD_POSIX)	return (env->tmpPool->pstrdup2ascii(env, env->tmpPool, s));#else	return (env->tmpPool->pstrdup(env, env->tmpPool, s));#endif}static int JK_METHOD jk2_channel_jni_init(jk_env_t *env,                                          jk_bean_t *jniWB){    jk_channel_t *jniW=jniWB->object;    jk_workerEnv_t *wEnv=jniW->workerEnv;    if (wEnv->childId != 0) {        if( jniW->worker != NULL )            jniW->worker->mbean->disabled=JK_TRUE;        return JK_ERR;    }    if( wEnv->vm == NULL ) {        env->l->jkLog(env, env->l, JK_LOG_INFO,                      "channel_jni.init() no VM found\n" );        if( jniW->worker != NULL ) {            jniW->worker->mbean->disabled=JK_TRUE;        }        return JK_ERR;    }    return JK_OK;}/** Assume the jni-worker or someone else started *  tomcat and initialized what is needed. */static int JK_METHOD jk2_channel_jni_open(jk_env_t *env,                                          jk_channel_t *_this,                                          jk_endpoint_t *endpoint){    jk_workerEnv_t *we=endpoint->worker->workerEnv;    JNIEnv *jniEnv;    jk_ch_jni_ep_private_t *epData;    jmethodID jmethod;    jobject jobj;    jstring jstr;    jk_channel_jni_private_t *jniCh=_this->_privatePtr;    if( endpoint->channelData != NULL ) {        env->l->jkLog(env, env->l, JK_LOG_INFO,                      "channel_jni.open() already open, nothing else to do\n");         return JK_OK;    }        env->l->jkLog(env, env->l, JK_LOG_INFO,"channel_jni.open():  \n" );    /* It is useless to continue if the channel worker        does not exist.     */    if( _this->worker == NULL ) {        env->l->jkLog(env, env->l, JK_LOG_ERROR,                      "channel_jni.open()  NullPointerException, no channel worker found\n");         return JK_ERR;    }        jniCh->vm=(jk_vm_t *)we->vm;    if( jniCh->vm == NULL ) {        env->l->jkLog(env, env->l, JK_LOG_ERROR,                      "channel_jni.open() no VM found\n" );         _this->worker->mbean->disabled=JK_TRUE;        return JK_ERR;    }    jniEnv = (JNIEnv *)jniCh->vm->attach( env, jniCh->vm );    if( jniEnv == NULL ) {        env->l->jkLog(env, env->l, JK_LOG_ERROR,                      "channel_jni.open() can't attach\n" );         _this->worker->mbean->disabled=JK_TRUE;        return JK_ERR;    }    /* Create the buffers used by the write method. We allocate a       byte[] and jbyte[] - I have no idea what's more expensive,       to copy a buffer or to 'pin' the jbyte[] for copying.       This will be tuned if needed, for now it seems the easiest       solution    */    epData=(jk_ch_jni_ep_private_t *)        endpoint->mbean->pool->calloc( env,endpoint->mbean->pool,                                       sizeof( jk_ch_jni_ep_private_t ));        endpoint->channelData=epData;    /* AS400/BS2000 need EBCDIC to ASCII conversion for JNI */    jniCh->jniBridge = (*jniEnv)->FindClass(jniEnv, strdup_ascii(env, jniCh->className) );        if( jniCh->jniBridge == NULL ) {        env->l->jkLog(env, env->l, JK_LOG_ERROR,                      "channel_jni.open() can't find %s\n",jniCh->className );         _this->worker->mbean->disabled=JK_TRUE;        return JK_ERR;    }    jniCh->jniBridge=(*jniEnv)->NewGlobalRef( jniEnv, jniCh->jniBridge);    if( jniCh->jniBridge == NULL ) {        env->l->jkLog(env, env->l, JK_LOG_ERROR,                      "channel_jni.open() Unable to allocate globalref for %s\n",jniCh->className );         _this->worker->mbean->disabled=JK_TRUE;        return JK_ERR;    }    /* Interface to the callback mechansim. The idea is simple ( is it ? ) - we       use a similar pattern with java, trying to do as little as possible       in C and pass minimal information to allow this.       The pattern used for callback works for our message forwarding but also for       other things - like singnals, etc    */    /* AS400/BS2000 need EBCDIC to ASCII conversion for JNI */    jmethod=(*jniEnv)->GetStaticMethodID(jniEnv, jniCh->jniBridge,                 strdup_ascii(env, "createJavaContext"),                  strdup_ascii(env, "(Ljava/lang/String;J)Ljava/lang/Object;"));    if( jmethod == NULL ) {        env->l->jkLog(env, env->l, JK_LOG_ERROR,                      "channel_jni.open() can't find createJavaContext\n");         _this->worker->mbean->disabled=JK_TRUE;        if( (*jniEnv)->ExceptionCheck( jniEnv ) ) {            (*jniEnv)->ExceptionClear( jniEnv );        }        return JK_ERR;    }        /* AS400/BS2000 need EBCDIC to ASCII conversion for JNI */    jstr=(*jniEnv)->NewStringUTF(jniEnv, strdup_ascii(env, "channelJni" ));        jobj=(*jniEnv)->CallStaticObjectMethod( jniEnv, jniCh->jniBridge,                                            jmethod,                                            jstr,                                             (jlong)(long)(void *)endpoint->mbean );    if( jobj  == NULL ) {        env->l->jkLog(env, env->l, JK_LOG_ERROR,                      "channel_jni.open() Can't create java context\n" );         epData->jniJavaContext=NULL;        _this->worker->mbean->disabled=JK_TRUE;        if( (*jniEnv)->ExceptionCheck( jniEnv ) ) {            (*jniEnv)->ExceptionClear( jniEnv );        }        return JK_ERR;    }    epData->jniJavaContext=(*jniEnv)->NewGlobalRef( jniEnv, jobj );    env->l->jkLog(env, env->l, JK_LOG_INFO,                  "channel_jni.open() Got ep %#lx %#lx\n", jobj, epData->jniJavaContext );     /* XXX Destroy them in close */        /* AS400/BS2000 need EBCDIC to ASCII conversion for JNI */    jmethod=(*jniEnv)->GetStaticMethodID(jniEnv, jniCh->jniBridge,                                         strdup_ascii(env, "getBuffer"),                                         strdup_ascii(env, "(Ljava/lang/Object;I)[B"));    if( jmethod == NULL ) {        env->l->jkLog(env, env->l, JK_LOG_ERROR,                      "channel_jni.open() can't find getBuffer\n");         _this->worker->mbean->disabled=JK_TRUE;        return JK_ERR;    }    epData->jarray=(*jniEnv)->CallStaticObjectMethod( jniEnv, jniCh->jniBridge,                                                      jmethod,                                                      epData->jniJavaContext, 0);    epData->jarray=(*jniEnv)->NewGlobalRef( jniEnv, epData->jarray );    epData->arrayLen = (*jniEnv)->GetArrayLength( jniEnv, epData->jarray );        /* XXX > ajp buffer size. Don't know how to fragment or reallocate       yet */    epData->carray=(char *)endpoint->mbean->pool->calloc( env, endpoint->mbean->pool,                                                          epData->arrayLen);    /* AS400/BS2000 need EBCDIC to ASCII conversion for JNI */    jniCh->writeMethod =        (*jniEnv)->GetStaticMethodID(jniEnv, jniCh->jniBridge,                                     strdup_ascii(env, "jniInvoke"),                                     strdup_ascii(env, "(JLjava/lang/Object;)I"));        if( jniCh->writeMethod == NULL ) {        env->l->jkLog(env, env->l, JK_LOG_EMERG,                      "channel_jni.open() can't find jniInvoke\n");                 _this->worker->mbean->disabled=JK_TRUE;        return JK_ERR;    }    env->l->jkLog(env, env->l, JK_LOG_INFO,                  "channel_jni.open() found write method, open ok\n" );     _this->worker->mbean->disabled=JK_FALSE;        /* Don't detach ( XXX Need to find out when the thread is     *  closing in order for this to work )     */    /*     jniCh->vm->detach( env, jniCh->vm ); */    return JK_OK;}/**  */static int JK_METHOD jk2_channel_jni_close(jk_env_t *env,jk_channel_t *_this,                                           jk_endpoint_t *endpoint){    jk_ch_jni_ep_private_t *epData;    JNIEnv *jniEnv;    jk_channel_jni_private_t *jniCh=_this->_privatePtr;    epData=(jk_ch_jni_ep_private_t *)endpoint->channelData;    if (epData == NULL) {        env->l->jkLog(env, env->l, JK_LOG_INFO,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -