mturk       2002/07/11 04:38:13

  Modified:    jk/native2/common jk_worker_jni.c
  Log:
  Introduce the worker.jni hooks.
  There are 4 types of hooks right now:
  1. onStartup : executes on load, redirect i/o and registeres natives
  2. onInit : executes on load
  3. onClose : executes on shutdown
  4. onShutdown : executes on shutdown and unloads VM
  All the hooks executes the java class=xxx but in the different process stages
  of the connector.
  
  Revision  Changes    Path
  1.26      +105 -70   jakarta-tomcat-connectors/jk/native2/common/jk_worker_jni.c
  
  Index: jk_worker_jni.c
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-connectors/jk/native2/common/jk_worker_jni.c,v
  retrieving revision 1.25
  retrieving revision 1.26
  diff -u -r1.25 -r1.26
  --- jk_worker_jni.c   10 Jul 2002 17:41:40 -0000      1.25
  +++ jk_worker_jni.c   11 Jul 2002 11:38:12 -0000      1.26
  @@ -84,6 +84,13 @@
   #define JAVA_BRIDGE_CLASS_NAME ("org/apache/jk/apr/TomcatStarter")
   #define JAVA_BRIDGE_CLASS_APRI ("org/apache/jk/apr/AprImpl")
   
  +/* The class will be executed when the connector is started */
  +#define JK2_WORKER_HOOK_STARTUP     0
  +#define JK2_WORKER_HOOK_INIT        1
  +#define JK2_WORKER_HOOK_CLOSE       2
  +/* The class will be executed when the connector is about to be destroyed */
  +#define JK2_WORKER_HOOK_SHUTDOWN    3
  +
   struct jni_worker_data {
       jclass      jk_java_bridge_class;
       jclass      jk_java_bridge_apri_class;
  @@ -97,6 +104,7 @@
       char **classNameOptions;
       char **args;
       int nArgs;
  +    int hook;
   };
   
   typedef struct jni_worker_data jni_worker_data_t;
  @@ -112,30 +120,32 @@
                                        "main", 
                                        "([Ljava/lang/String;)V");
       if(!p->jk_main_method) {
  -         env->l->jkLog(env, env->l, JK_LOG_EMERG, "Can't find main(String [])\n"); 
  -         return JK_ERR;
  +        env->l->jkLog(env, env->l, JK_LOG_EMERG, "Can't find main(String [])\n"); 
  +        return JK_ERR;
       }
  -
  -    p->jk_setout_method =
  +    /* Only the startup hook can redirect the stdout/stderr */
  +    if (p->hook == JK2_WORKER_HOOK_STARTUP) {
  +        p->jk_setout_method =
           (*jniEnv)->GetStaticMethodID(jniEnv, p->jk_java_bridge_apri_class,
                                        "setOut", 
                                        "(Ljava/lang/String;)V");
  -    if(!p->jk_setout_method) {
  -         env->l->jkLog(env, env->l, JK_LOG_EMERG, "Can't find 
AprImpl.setOut(String)"); 
  -         return JK_ERR;
  -    }
  +        if(!p->jk_setout_method) {
  +            env->l->jkLog(env, env->l, JK_LOG_EMERG, 
  +                          "Can't find AprImpl.setOut(String)"); 
  +            return JK_ERR;
  +        }
   
  -    p->jk_seterr_method =
  +        p->jk_seterr_method =
           (*jniEnv)->GetStaticMethodID(jniEnv, p->jk_java_bridge_apri_class,
                                        "setErr", 
                                        "(Ljava/lang/String;)V");
  -    if(!p->jk_seterr_method) {
  -         env->l->jkLog(env, env->l, JK_LOG_EMERG, "Can't find 
AprImpl.setErr(String)\n"); 
  -         return JK_ERR;
  +        if(!p->jk_seterr_method) {
  +            env->l->jkLog(env, env->l, JK_LOG_EMERG, 
  +                          "Can't find AprImpl.setErr(String)\n"); 
  +            return JK_ERR;
  +        }
       }
   
  -    
  -
       return JK_OK;
   }
   
  @@ -154,7 +164,7 @@
       char *value=valueP;
       jni_worker_data_t *jniWorker;
       int mem_config = 0;
  -
  +    
       if(! _this || ! _this->worker_private) {
           env->l->jkLog(env, env->l, JK_LOG_ERROR,
                         "In validate, assert failed - invalid parameters\n");
  @@ -162,6 +172,16 @@
       }
   
       jniWorker = _this->worker_private;
  +    if (strcmp(mbean->name, "worker.jni:onStartup") == 0)
  +        jniWorker->hook = JK2_WORKER_HOOK_STARTUP;
  +    else if (strncmp(mbean->name, "worker.jni:onInit",
  +        sizeof("worker.jni:onInit") -1)== 0)
  +        jniWorker->hook = JK2_WORKER_HOOK_INIT;
  +    else if (strncmp(mbean->name, "worker.jni:onClose",
  +        sizeof("worker.jni:onClose") -1)== 0)
  +        jniWorker->hook = JK2_WORKER_HOOK_CLOSE;
  +    else if (strcmp(mbean->name, "worker.jni:onShutdown") == 0)
  +        jniWorker->hook = JK2_WORKER_HOOK_SHUTDOWN;
   
       if( strcmp( name, "stdout" )==0 ) {
           jniWorker->stdout_name = value;
  @@ -178,10 +198,6 @@
           } else {
               jniWorker->className = value;
           }
  -    /* XXX Instead of ARG=start split to something like:
  -     * startup=start
  -     * shutdown=stop
  -     */
       } else if( strcmp( name, "ARG" )==0 ) {
           jniWorker->args[jniWorker->nArgs]=value;
           jniWorker->nArgs++;
  @@ -273,9 +289,9 @@
                     "Loaded %s\n", jniWorker->className);
   
   /* Instead of loading mod_jk2.so from java, use the JNI RegisterGlobals.
  -   XXX Need the way to customize JAVA_BRIDGE_CLASS_APRI, but since
  -   it's hardcoded in JniHandler.java doesn't matter for now.
  -*/
  + * XXX Need the way to customize JAVA_BRIDGE_CLASS_APRI, but since
  + * it's hardcoded in JniHandler.java doesn't matter for now.
  + */
       jniWorker->jk_java_bridge_apri_class =
           (*jniEnv)->FindClass(jniEnv, JAVA_BRIDGE_CLASS_APRI );
   
  @@ -286,14 +302,17 @@
           vm->detach(env, vm);
           return JK_ERR;
       }
  -    rc = jk_jni_aprImpl_registerNatives( jniEnv, 
jniWorker->jk_java_bridge_apri_class);
  -    if( rc != 0) {
  -     env->l->jkLog(env, env->l, JK_LOG_ERROR,
  -                      "Can't register native functions for %s \n", 
JAVA_BRIDGE_CLASS_APRI ); 
  -        vm->detach(env, vm);
  -        return JK_ERR;
  +
  +    if (jniWorker->hook == JK2_WORKER_HOOK_STARTUP) {
  +        rc = jk_jni_aprImpl_registerNatives( jniEnv, 
jniWorker->jk_java_bridge_apri_class);
  +        if( rc != 0) {
  +            env->l->jkLog(env, env->l, JK_LOG_ERROR,
  +                          "Can't register native functions for %s \n", 
JAVA_BRIDGE_CLASS_APRI ); 
  +            vm->detach(env, vm);
  +            return JK_ERR;
  +        }
       }
  -    
  +
       rc=jk2_get_method_ids(env, jniWorker, jniEnv);
       if( rc!=JK_OK ) {
           env->l->jkLog(env, env->l, JK_LOG_EMERG,
  @@ -302,21 +321,6 @@
           vm->detach(env, vm);
           return rc;
       }
  -
  -    jstringClass=(*jniEnv)->FindClass(jniEnv, "java/lang/String" );
  -
  -    jargs=(*jniEnv)->NewObjectArray(jniEnv, jniWorker->nArgs, jstringClass, NULL);
  -
  -    for( i=0; i<jniWorker->nArgs; i++ ) {
  -        jstring arg=NULL;
  -        if( jniWorker->args[i] != NULL ) {
  -            arg=(*jniEnv)->NewStringUTF(jniEnv, jniWorker->args[i] );
  -            env->l->jkLog(env, env->l, JK_LOG_INFO,
  -                          "jni.init() ARG %s\n", jniWorker->args[i]);
  -        }
  -        (*jniEnv)->SetObjectArrayElement(jniEnv, jargs, i, arg );        
  -    }
  -    
       /* Set out and err stadard files */ 
       if (jniWorker->stdout_name && jniWorker->jk_setout_method) {
           env->l->jkLog(env, env->l, JK_LOG_INFO,
  @@ -335,16 +339,38 @@
                                           jniWorker->jk_seterr_method,
                                           stderr_name);
       }
  -    env->l->jkLog(env, env->l, JK_LOG_INFO,
  -                  "jni.init() calling main()...\n");
  -    (*jniEnv)->CallStaticVoidMethod(jniEnv,
  -                                    jniWorker->jk_java_bridge_class,
  -                                    jniWorker->jk_main_method,
  -                                    jargs);
  +    
  +    if (jniWorker->hook < JK2_WORKER_HOOK_CLOSE) {
  +        jstringClass=(*jniEnv)->FindClass(jniEnv, "java/lang/String" );
  +
  +        jargs=(*jniEnv)->NewObjectArray(jniEnv, jniWorker->nArgs, jstringClass, 
NULL);
  +
  +        for( i=0; i<jniWorker->nArgs; i++ ) {
  +            jstring arg=NULL;
  +            if( jniWorker->args[i] != NULL ) {
  +                arg=(*jniEnv)->NewStringUTF(jniEnv, jniWorker->args[i] );
  +                env->l->jkLog(env, env->l, JK_LOG_INFO,
  +                              "jni.init() ARG %s\n", jniWorker->args[i]);
  +            }
  +            (*jniEnv)->SetObjectArrayElement(jniEnv, jargs, i, arg );        
  +        }
  +    
  +        env->l->jkLog(env, env->l, JK_LOG_INFO,
  +                      "jni.init() calling main()...\n");
  +        (*jniEnv)->CallStaticVoidMethod(jniEnv,
  +                                        jniWorker->jk_java_bridge_class,
  +                                        jniWorker->jk_main_method,
  +                                        jargs);
  +    }
  +    else {
  +        /* XXX Is it right thing to disable all non init hooks 
  +         * or make that customizable.
  +         */
  +        env->l->jkLog(env, env->l, JK_LOG_INFO,
  +                      "jni.init() disabling the non init hook worker\n");
  +        _this->mbean->disabled = 1;
  +    }
   #if 0
  -    /* Do not detach the main thread.
  -     * It will be detached on destroy
  -     */
       vm->detach(env, vm);
   #endif
       /* XXX create a jni channel */
  @@ -363,7 +389,7 @@
       jclass jstringClass;
       jarray jargs;
       jstring arg=NULL;
  -    
  +
       if(!_this  || ! _this->worker_private) {
           env->l->jkLog(env, env->l, JK_LOG_EMERG,
                         "In destroy, assert failed - invalid parameters\n");
  @@ -371,21 +397,29 @@
       }
   
       jniWorker = _this->worker_private;
  -
  +    
  +    if (jniWorker->hook < JK2_WORKER_HOOK_CLOSE) {
  +        env->l->jkLog(env, env->l, JK_LOG_INFO,
  +                       "jni.destroy(), done...worker is not hooked for close\n");
  +        return JK_OK;
  +    }
       if((jniEnv = vm->attach(env, vm))) {
  +        int i;
           env->l->jkLog(env, env->l, JK_LOG_INFO,
                          "jni.destroy(), shutting down Tomcat...\n");
   
           jstringClass=(*jniEnv)->FindClass(jniEnv, "java/lang/String" );
  -        jargs=(*jniEnv)->NewObjectArray(jniEnv, 1, jstringClass, NULL);
  +        jargs=(*jniEnv)->NewObjectArray(jniEnv, jniWorker->nArgs, jstringClass, 
NULL);
  +        for( i=0; i<jniWorker->nArgs; i++ ) {
  +            jstring arg=NULL;
  +            if( jniWorker->args[i] != NULL ) {
  +                arg=(*jniEnv)->NewStringUTF(jniEnv, jniWorker->args[i] );
  +                env->l->jkLog(env, env->l, JK_LOG_INFO,
  +                                "jni.init() ARG %s\n", jniWorker->args[i]);
  +            }
  +            (*jniEnv)->SetObjectArrayElement(jniEnv, jargs, i, arg );        
  +        }
   
  -        /* XXX Need to make that arg customizable 
  -        */
  -        arg=(*jniEnv)->NewStringUTF(jniEnv, "stop" );
  -        env->l->jkLog(env, env->l, JK_LOG_INFO,
  -                          "jni.destroy() ARG stop\n");
  -        (*jniEnv)->SetObjectArrayElement(jniEnv, jargs, 0, arg );        
  -    
           env->l->jkLog(env, env->l, JK_LOG_INFO,
                         "jni.destroy() calling main()...\n");
   
  @@ -393,15 +427,16 @@
           (*jniEnv)->CallStaticVoidMethod(jniEnv,
                                       jniWorker->jk_java_bridge_class,
                                       jniWorker->jk_main_method,
  -                                    jargs,stdout_name,stderr_name);
  +                                    jargs);
  +        if (jniWorker->hook == JK2_WORKER_HOOK_SHUTDOWN) {
   #ifdef HAS_APR
  -        while (jk_jni_status_code != 2) {
  -            apr_thread_yield();
  -        }
  +            while (jk_jni_status_code != 2) {
  +                apr_thread_yield();
  +            }
   #endif
  -        (*jniEnv)->UnregisterNatives(jniEnv, jniWorker->jk_java_bridge_apri_class);
  -
  -        vm->destroy(env, vm);
  +            (*jniEnv)->UnregisterNatives(jniEnv, 
jniWorker->jk_java_bridge_apri_class);
  +            vm->destroy(env, vm);
  +        }
       }
       env->l->jkLog(env, env->l, JK_LOG_INFO, "jni.destroy() done\n");
   
  
  
  

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to