diff options
Diffstat (limited to 'ext/java/java.c')
| -rw-r--r-- | ext/java/java.c | 151 | 
1 files changed, 108 insertions, 43 deletions
| diff --git a/ext/java/java.c b/ext/java/java.c index 9d0cf7516e..83db3d4b7a 100644 --- a/ext/java/java.c +++ b/ext/java/java.c @@ -68,12 +68,33 @@ static char *javahome  = 0;  static char *javalib   = 0;  static int iniUpdated  = 0; - -static JavaVM *jvm = 0; -static JNIEnv *jenv = 0; -static jclass php_reflect;  static void *dl_handle = 0; +typedef struct { +  JavaVM *jvm; +  JNIEnv *jenv; +  jobject php_reflect; +  jclass  reflect_class; +} php_java_globals; + +#ifdef ZTS +#define JG(v) (java_globals->v) +#define JG_FETCH() php_java_globals *java_globals = ts_resource(java_globals_id) +#define JG_D       php_java_globals *java_globals +#define JG_DC      , JG_D +#define JG_C       dir_globals +#define JG_CC      , JG_C +int java_globals_id; +#else +#define JG(v) (java_globals.v) +#define JG_FETCH() +#define JG_D +#define JG_DC +#define JG_C +#define JG_CC +php_java_globals javadir_globals; +#endif +  static zend_class_entry java_class_entry;  static PHP_INI_MH(OnIniUpdate) { @@ -106,15 +127,17 @@ PHP_INI_END()   * Destroy a Java Virtual Machine.   */  void jvm_destroy() { -  if (php_reflect) (*jenv)->DeleteGlobalRef(jenv, php_reflect); -  if (jvm) { -    (*jvm)->DetachCurrentThread(jvm); -    (*jvm)->DestroyJavaVM(jvm); -    jvm = 0; +  JG_FETCH(); + +  if (JG(php_reflect)) (*JG(jenv))->DeleteGlobalRef(JG(jenv), JG(php_reflect)); +  if (JG(jvm)) { +    (*JG(jvm))->DetachCurrentThread(JG(jvm)); +    (*JG(jvm))->DestroyJavaVM(JG(jvm)); +    JG(jvm) = 0;    }    if (dl_handle) DL_UNLOAD(dl_handle); -  php_reflect = 0; -  jenv = 0; +  JG(php_reflect) = 0; +  JG(jenv) = 0;  }  /* @@ -134,9 +157,10 @@ static void addJVMOption(JavaVMInitArgs *vm_args, char *name, char *value) {  #endif  static int jvm_create() { +  JG_FETCH();    int rc; -  jclass local_php_reflect; +  jobject local_php_reflect;    jthrowable error;    jint (JNICALL *JNI_CreateVM)(const void*,const void*,void*); @@ -217,21 +241,22 @@ static int jvm_create() {  #endif -  rc = (*JNI_CreateVM)(&jvm, &jenv, &vm_args); +  rc = (*JNI_CreateVM)(&JG(jvm), &JG(jenv), &vm_args);    if (rc) {      php_error(E_ERROR, "Unable to create Java Virtual Machine");      return rc;    } -  local_php_reflect = (*jenv)->FindClass(jenv, "net/php/reflect"); -  error = (*jenv)->ExceptionOccurred(jenv); +  JG(reflect_class) = (*JG(jenv))->FindClass(JG(jenv), "net/php/reflect"); +  error = (*JG(jenv))->ExceptionOccurred(JG(jenv));    if (error) {      jclass errClass;      jmethodID toString;      jobject errString;      const char *errAsUTF;      jboolean isCopy; +    JNIEnv *jenv = JG(jenv);      (*jenv)->ExceptionClear(jenv);      errClass = (*jenv)->GetObjectClass(jenv, error);      toString = (*jenv)->GetMethodID(jenv, errClass, "toString", @@ -244,13 +269,17 @@ static int jvm_create() {      return -1;    } -  php_reflect = (*jenv)->NewGlobalRef(jenv, local_php_reflect); +  local_php_reflect = (*JG(jenv))->AllocObject(JG(jenv), JG(reflect_class)); +  JG(php_reflect) = (*JG(jenv))->NewGlobalRef(JG(jenv), local_php_reflect);    return rc;  }  /***************************************************************************/  static jobjectArray _java_makeArray(int argc, pval** argv) { +  JG_FETCH(); +  JNIEnv *jenv = JG(jenv); +    jclass objectClass = (*jenv)->FindClass(jenv, "java/lang/Object");    jobjectArray result = (*jenv)->NewObjectArray(jenv, argc, objectClass, 0);    jobject arg; @@ -273,23 +302,23 @@ static jobjectArray _java_makeArray(int argc, pval** argv) {          break;        case IS_BOOL: -        makeArg = (*jenv)->GetStaticMethodID(jenv, php_reflect, "MakeArg", +        makeArg = (*jenv)->GetMethodID(jenv, JG(reflect_class), "MakeArg",            "(Z)Ljava/lang/Object;"); -        arg = (*jenv)->CallStaticObjectMethod(jenv, php_reflect, makeArg, +        arg = (*jenv)->CallObjectMethod(jenv, JG(php_reflect), makeArg,            (jboolean)(argv[i]->value.lval));          break;        case IS_LONG: -        makeArg = (*jenv)->GetStaticMethodID(jenv, php_reflect, "MakeArg", +        makeArg = (*jenv)->GetMethodID(jenv, JG(reflect_class), "MakeArg",            "(J)Ljava/lang/Object;"); -        arg = (*jenv)->CallStaticObjectMethod(jenv, php_reflect, makeArg, +        arg = (*jenv)->CallObjectMethod(jenv, JG(php_reflect), makeArg,            (jlong)(argv[i]->value.lval));          break;        case IS_DOUBLE: -        makeArg = (*jenv)->GetStaticMethodID(jenv, php_reflect, "MakeArg", +        makeArg = (*jenv)->GetMethodID(jenv, JG(reflect_class), "MakeArg",            "(D)Ljava/lang/Object;"); -        arg = (*jenv)->CallStaticObjectMethod(jenv, php_reflect, makeArg, +        arg = (*jenv)->CallObjectMethod(jenv, JG(php_reflect), makeArg,            (jdouble)(argv[i]->value.dval));          break; @@ -323,6 +352,9 @@ static int checkError(pval *value) {  void java_call_function_handler    (INTERNAL_FUNCTION_PARAMETERS, zend_property_reference *property_reference)  { +  JG_FETCH(); +  JNIEnv *jenv; +    pval *object = property_reference->object;    zend_overloaded_element *function_name = (zend_overloaded_element *)      property_reference->elements_list->tail->data; @@ -333,9 +365,10 @@ void java_call_function_handler    pval **arguments = (pval **) emalloc(sizeof(pval *)*arg_count);    getParametersArray(ht, arg_count, arguments); -  if (iniUpdated && jenv) jvm_destroy(); -  if (!jenv) jvm_create(); -  if (!jenv) return; +  if (iniUpdated && JG(jenv)) jvm_destroy(); +  if (!JG(jenv)) jvm_create(); +  if (!JG(jenv)) return; +  jenv = JG(jenv);    if (!strcmp("java",function_name->element.value.str.val)) { @@ -343,12 +376,12 @@ void java_call_function_handler         First argument is the class name.  Any additional arguments will         be treated as constructor parameters. */ -    jmethodID co = (*jenv)->GetStaticMethodID(jenv, php_reflect, "CreateObject", +    jmethodID co = (*jenv)->GetMethodID(jenv, JG(reflect_class), "CreateObject",        "(Ljava/lang/String;[Ljava/lang/Object;J)V");      jstring className=(*jenv)->NewStringUTF(jenv, arguments[0]->value.str.val);      (pval*)(long)result = object; -    (*jenv)->CallStaticVoidMethod(jenv, php_reflect, co, +    (*jenv)->CallVoidMethod(jenv, JG(php_reflect), co,        className, _java_makeArray(arg_count-1, arguments+1), result);      (*jenv)->DeleteLocalRef(jenv, className); @@ -362,14 +395,14 @@ void java_call_function_handler      /* invoke a method on the given object */ -    jmethodID invoke = (*jenv)->GetStaticMethodID(jenv, php_reflect, "Invoke", +    jmethodID invoke = (*jenv)->GetMethodID(jenv, JG(reflect_class), "Invoke",        "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;J)V");      zend_hash_index_find(object->value.obj.properties, 0, (void**) &handle);      obj = zend_list_find((*handle)->value.lval, &type);      method = (*jenv)->NewStringUTF(jenv, function_name->element.value.str.val);      (pval*)(long)result = return_value; -    (*jenv)->CallStaticVoidMethod(jenv, php_reflect, invoke, +    (*jenv)->CallVoidMethod(jenv, JG(php_reflect), invoke,        obj, method, _java_makeArray(arg_count, arguments), result);      (*jenv)->DeleteLocalRef(jenv, method); @@ -386,30 +419,38 @@ void java_call_function_handler  PHP_FUNCTION(java_last_exception_get)  { +  JG_FETCH(); +    jlong result = 0;    jmethodID lastEx; +  if (ZEND_NUM_ARGS()!=0) WRONG_PARAM_COUNT; +    (pval*)(long)result = return_value; -  lastEx = (*jenv)->GetStaticMethodID(jenv, php_reflect, "lastException", -          "(J)V"); +  lastEx = (*JG(jenv))->GetMethodID(JG(jenv), JG(reflect_class),  +          "lastException", "(J)V"); -  (*jenv)->CallStaticVoidMethod(jenv, php_reflect, lastEx, result); +  (*JG(jenv))->CallVoidMethod(JG(jenv), JG(php_reflect), lastEx, result);  }  /***************************************************************************/  PHP_FUNCTION(java_last_exception_clear)  { +  JG_FETCH(); +    jlong result = 0;    jmethodID clearEx; +  if (ZEND_NUM_ARGS()!=0) WRONG_PARAM_COUNT; +    (pval*)(long)result = return_value; -  clearEx = (*jenv)->GetStaticMethodID(jenv, php_reflect, "clearException", -          "()V"); +  clearEx = (*JG(jenv))->GetMethodID(JG(jenv), JG(reflect_class),  +          "clearException", "()V"); -  (*jenv)->CallStaticVoidMethod(jenv, php_reflect, clearEx); +  (*JG(jenv))->CallVoidMethod(JG(jenv), JG(php_reflect), clearEx);  }  /***************************************************************************/ @@ -417,6 +458,9 @@ PHP_FUNCTION(java_last_exception_clear)  static pval _java_getset_property    (zend_property_reference *property_reference, jobjectArray value)  { +  JG_FETCH(); +  JNIEnv *jenv = JG(jenv); +    pval presult;    jlong result = 0;    pval **pobject; @@ -441,10 +485,10 @@ static pval _java_getset_property        "Attempt to access a Java property on a non-Java object");    } else {      /* invoke the method */ -    jmethodID gsp = (*jenv)->GetStaticMethodID(jenv, php_reflect, "GetSetProp", +    jmethodID gsp = (*jenv)->GetMethodID(jenv, JG(reflect_class), "GetSetProp",        "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;J)V"); -    (*jenv)->CallStaticVoidMethod -       (jenv, php_reflect, gsp, obj, propName, value, result); +    (*jenv)->CallVoidMethod +       (jenv, JG(php_reflect), gsp, obj, propName, value, result);    }    (*jenv)->DeleteLocalRef(jenv, propName); @@ -472,9 +516,16 @@ int java_set_property_handler  /***************************************************************************/  static void _php_java_destructor(void *jobject) { -  if (jenv) (*jenv)->DeleteGlobalRef(jenv, jobject); +  JG_FETCH(); +  if (JG(jenv)) (*JG(jenv))->DeleteGlobalRef(JG(jenv), jobject);  } +#ifdef ZTS +static void alloc_java_globals_ctor(php_java_globals *java_globals) { +  memset(java_globals, 0, sizeof(php_java_globals)); +} +#endif +  PHP_MINIT_FUNCTION(java) {    INIT_OVERLOADED_CLASS_ENTRY(java_class_entry, "java", NULL,      java_call_function_handler, @@ -494,13 +545,19 @@ PHP_MINIT_FUNCTION(java) {      libpath=PG(extension_dir);    } +#ifdef ZTS +  java_globals_id = ts_allocate_id(sizeof(php_java_globals),  +    (ts_allocate_ctor)alloc_java_globals_ctor, NULL); +#endif +    return SUCCESS;  }  PHP_MSHUTDOWN_FUNCTION(java) { +  JG_FETCH();    UNREGISTER_INI_ENTRIES(); -  if (jvm) jvm_destroy(); +  if (JG(jvm)) jvm_destroy();    return SUCCESS;  } @@ -620,8 +677,16 @@ JNIEXPORT void JNICALL Java_net_php_reflect_setException  JNIEXPORT void JNICALL Java_net_php_reflect_setEnv    (JNIEnv *newJenv, jclass self)  { +  JG_FETCH(); +  jobject local_php_reflect; +    iniUpdated=0; -  jenv=newJenv; -  if (!self) self = (*jenv)->FindClass(jenv, "net/php/reflect"); -  php_reflect = (*jenv)->NewGlobalRef(jenv, self); +  JG(jenv)=newJenv; + +  if (!self) self = (*JG(jenv))->FindClass(JG(jenv), "net/php/reflect"); +  JG(reflect_class) = self; + +  if (JG(php_reflect)) (*JG(jenv))->DeleteGlobalRef(JG(jenv), JG(php_reflect)); +  local_php_reflect = (*JG(jenv))->AllocObject(JG(jenv), JG(reflect_class)); +  JG(php_reflect) = (*JG(jenv))->NewGlobalRef(JG(jenv), local_php_reflect);  } | 
