📄 jk_channel_jni.c
字号:
"channel_jni.close() no channel data\n" ); return JK_ERR; } jniEnv = (JNIEnv *)jniCh->vm->attach( env, jniCh->vm ); if( jniEnv == NULL ) { env->l->jkLog(env, env->l, JK_LOG_INFO, "channel_jni.close() can't attach\n" ); return JK_ERR; } if( epData->jarray != NULL ){ (*jniEnv)->DeleteGlobalRef( jniEnv, epData->jarray ); } if( epData->jniJavaContext != NULL){ (*jniEnv)->DeleteGlobalRef( jniEnv, epData->jniJavaContext ); } jniCh->vm->detach( env, jniCh->vm ); env->l->jkLog(env, env->l, JK_LOG_INFO, "channel_jni.close() ok\n" ); endpoint->channelData=NULL; return JK_OK;}/** send a long message * @param sd opened socket. * @param b buffer containing the data. * @param len length to send. * @return -2: send returned 0 ? what this that ? * -3: send failed. * >0: total size send. * @bug this fails on Unixes if len is too big for the underlying * protocol. * @was: jk_tcp_socket_sendfull */static int JK_METHOD jk2_channel_jni_send(jk_env_t *env, jk_channel_t *_this, jk_endpoint_t *endpoint, jk_msg_t *msg) {/* int sd; */ int sent=0; char *b; int len; jbyte *nbuf; jbyteArray jbuf; int jlen=0; jboolean iscopy=0; JNIEnv *jniEnv; jk_channel_jni_private_t *jniCh=_this->_privatePtr; jk_ch_jni_ep_private_t *epData= (jk_ch_jni_ep_private_t *)endpoint->channelData; if( _this->mbean->debug > 0 ) env->l->jkLog(env, env->l, JK_LOG_DEBUG,"channel_jni.send() %#lx\n", epData ); if( epData == NULL ) { jk2_channel_jni_open( env, _this, endpoint ); epData=(jk_ch_jni_ep_private_t *)endpoint->channelData; } if( epData == NULL ){ env->l->jkLog(env, env->l, JK_LOG_ERROR,"channel_jni.send() error opening channel\n" ); return JK_ERR; } if( epData->jniJavaContext == NULL ) { env->l->jkLog(env, env->l, JK_LOG_ERROR,"channel_jni.send() no java context\n" ); jk2_channel_jni_close( env, _this, endpoint ); return JK_ERR; } msg->end( env, msg ); len=msg->len; b=msg->buf; if( _this->mbean->debug > 0 ) env->l->jkLog(env, env->l, JK_LOG_DEBUG,"channel_jni.send() (1) %#lx\n", epData ); jniEnv=NULL; /* epData->jniEnv; */ jbuf=epData->jarray; if( jniCh->writeMethod == NULL ) { env->l->jkLog(env, env->l, JK_LOG_EMERG, "channel_jni.send() no write method\n" ); return JK_ERR; } if( jniEnv==NULL ) { /* Try first getEnv, then attach */ jniEnv = (JNIEnv *)jniCh->vm->attach( env, jniCh->vm ); if( jniEnv == NULL ) { env->l->jkLog(env, env->l, JK_LOG_INFO, "channel_jni.send() can't attach\n" ); return JK_ERR; } } if( _this->mbean->debug > 0 ) env->l->jkLog(env, env->l, JK_LOG_DEBUG, "channel_jni.send() getting byte array \n" ); /* Copy the data in the ( recycled ) jbuf, then call the * write method. XXX We could try 'pining' if the vm supports * it, this is a looong lived object. */#ifdef JK_JNI_CRITICAL nbuf = (*jniEnv)->GetPrimitiveArrayCritical(jniEnv, jbuf, &iscopy);#else nbuf = (*jniEnv)->GetByteArrayElements(jniEnv, jbuf, &iscopy); #endif if( iscopy ) env->l->jkLog(env, env->l, JK_LOG_INFO, "channelJni.send() get java bytes iscopy %d\n", iscopy); if(nbuf==NULL ) { env->l->jkLog(env, env->l, JK_LOG_ERROR, "channelJni.send() Can't get java bytes"); return JK_ERR; } memcpy( nbuf, b, len );#ifdef JK_JNI_CRITICAL (*jniEnv)->ReleasePrimitiveArrayCritical(jniEnv, jbuf, nbuf, 0);#else (*jniEnv)->ReleaseByteArrayElements(jniEnv, jbuf, nbuf, 0);#endif if( _this->mbean->debug > 0 ) env->l->jkLog(env, env->l, JK_LOG_DEBUG, "channel_jni.send() before send %#lx\n", (void *)(long)epData->jniJavaContext); sent=(*jniEnv)->CallStaticIntMethod( jniEnv, jniCh->jniBridge, jniCh->writeMethod, (jlong)(long)(void *)env, epData->jniJavaContext ); if( _this->mbean->debug > 0 ) env->l->jkLog(env, env->l, JK_LOG_DEBUG,"channel_jni.send() result %d\n", sent); return JK_OK;}/** * Not used - we have a single thread, there is no 'blocking' - the * java side will send messages by calling a native method, which will * receive and dispatch. */static int JK_METHOD jk2_channel_jni_recv(jk_env_t *env, jk_channel_t *_this, jk_endpoint_t *endpoint, jk_msg_t *msg) {/* jbyte *nbuf; *//* jbyteArray jbuf; *//* int jlen; *//* jboolean iscommit; */ jk_channel_jni_private_t *jniCh=_this->_privatePtr; env->l->jkLog(env, env->l, JK_LOG_ERROR, "channelJni.recv() method not supported for JNI channel\n"); return -1; /* Old workaround: nbuf=(jbyte *)endpoint->currentData; if(nbuf==NULL ) { env->l->jkLog(env, env->l, JK_LOG_INFO, "channelJni.recv() no jbyte[] was received\n"); return -1; } env->l->jkLog(env, env->l, JK_LOG_INFO, "channelJni.recv() receiving %d\n", len); memcpy( b, nbuf + endpoint->currentOffset, len ); endpoint->currentOffset += len; return len; */}/** Called before request processing, to initialize resources. All following calls will be in the same thread.*/int JK_METHOD jk2_channel_jni_beforeRequest(struct jk_env *env, jk_channel_t *_this, struct jk_worker *worker, struct jk_endpoint *endpoint, struct jk_ws_service *r ){ jk_workerEnv_t *we=worker->workerEnv; if( worker->mbean->debug > 0 ) env->l->jkLog(env, env->l, JK_LOG_DEBUG, "service() attaching to vm\n"); return JK_OK;}/** Called after request processing. Used to be worker.done() */int JK_METHOD jk2_channel_jni_afterRequest(struct jk_env *env, jk_channel_t *_this, struct jk_worker *worker, struct jk_endpoint *endpoint, struct jk_ws_service *r ){ jk_workerEnv_t *we=worker->workerEnv; if( we==NULL || we->vm==NULL) { return JK_OK; } /* * In case of not having the endpoint detach the jvm. * XXX Remove calling this function from ajp13 worker? */ if (endpoint == NULL) we->vm->detach( env, we->vm ); if( worker->mbean->debug > 0 ) env->l->jkLog(env, env->l, JK_LOG_DEBUG, "channelJni.afterRequest() ok\n"); return JK_OK;}static int JK_METHOD jk2_channel_jni_setProperty(jk_env_t *env, jk_bean_t *mbean, char *name, void *valueP){ jk_channel_t *ch=(jk_channel_t *)mbean->object; char *value=valueP; jk_channel_jni_private_t *jniInfo= (jk_channel_jni_private_t *)(ch->_privatePtr); if( strcmp( "class", name ) == 0 ) { jniInfo->className=value; } /* TODO: apache protocol hooks else if( strcmp( "xxxx", name ) == 0 ) { jniInfo->xxxx=value; } */ else { return jk2_channel_setAttribute( env, mbean, name, valueP ); } return JK_OK;}/** Called by java. Will take the msg and dispatch it to workerEnv, as if it would * be if received via socket */int JK_METHOD jk2_channel_jni_invoke(jk_env_t *env, jk_bean_t *bean, jk_endpoint_t *ep, int code, jk_msg_t *msg, int raw){ jk_channel_t *ch=(jk_channel_t *)bean->object; int rc=JK_OK; if( ch->mbean->debug > 0 ) env->l->jkLog(env, env->l, JK_LOG_DEBUG, "ch.%d() \n", code); code = (int)msg->getByte(env, msg); if( ch->mbean->debug > 0 ) env->l->jkLog(env, env->l, JK_LOG_DEBUG,"channelJni.java2cInvoke() %d\n", code); return ep->worker->workerEnv->dispatch( env, ep->worker->workerEnv, ep->currentRequest, ep, code, ep->reply );}static int JK_METHOD jk2_channel_jni_status(jk_env_t *env, struct jk_worker *worker, jk_channel_t *_this){ jk_channel_jni_private_t *jniCh=_this->_privatePtr; if ( jniCh->status != JNI_TOMCAT_STARTED) { jniCh->status = jk_jni_status_code; if (jniCh->status != JNI_TOMCAT_STARTED) return JK_ERR; } return JK_OK;}int JK_METHOD jk2_channel_jni_factory(jk_env_t *env, jk_pool_t *pool, jk_bean_t *result, const char *type, const char *name){ jk_channel_t *ch=result->object; jk_workerEnv_t *wEnv; jk_channel_jni_private_t *jniPrivate; wEnv = env->getByName( env, "workerEnv" ); ch=(jk_channel_t *)pool->calloc(env, pool, sizeof( jk_channel_t)); ch->recv= jk2_channel_jni_recv; ch->send= jk2_channel_jni_send; ch->open= jk2_channel_jni_open; ch->close= jk2_channel_jni_close; ch->beforeRequest= jk2_channel_jni_beforeRequest; ch->afterRequest= jk2_channel_jni_afterRequest; ch->status = jk2_channel_jni_status; ch->_privatePtr=jniPrivate=(jk_channel_jni_private_t *)pool->calloc(env, pool, sizeof(jk_channel_jni_private_t)); jniPrivate->className = JAVA_BRIDGE_CLASS_NAME; ch->is_stream=JK_FALSE; /* No special attribute */ result->setAttribute= jk2_channel_jni_setProperty; ch->mbean=result; result->object= ch; result->init= jk2_channel_jni_init; ch->workerEnv=wEnv; wEnv->addChannel( env, wEnv, ch ); result->invoke=jk2_channel_jni_invoke; return JK_OK;}#elseint JK_METHOD jk2_channel_jni_factory(jk_env_t *env, jk_pool_t *pool, jk_bean_t *result, const char *type, const char *name){ result->disabled=1; return JK_OK;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -