diff options
author | Sam Ruby <rubys@php.net> | 2000-07-09 04:16:31 +0000 |
---|---|---|
committer | Sam Ruby <rubys@php.net> | 2000-07-09 04:16:31 +0000 |
commit | 629bc6708615edb74cc7dc3ec4723d7448df4029 (patch) | |
tree | cceec3d214b2f82ce95ace968ef3456062aab80c /ext/java/java.c | |
parent | 5c13954eed3a88deb0f00a0e3c840631a3d209d4 (diff) | |
download | php-git-629bc6708615edb74cc7dc3ec4723d7448df4029.tar.gz |
Reentrancy fixes
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); } |