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/rpc | |
parent | 5c13954eed3a88deb0f00a0e3c840631a3d209d4 (diff) | |
download | php-git-629bc6708615edb74cc7dc3ec4723d7448df4029.tar.gz |
Reentrancy fixes
Diffstat (limited to 'ext/rpc')
-rw-r--r-- | ext/rpc/java/README | 6 | ||||
-rw-r--r-- | ext/rpc/java/java.c | 151 | ||||
-rw-r--r-- | ext/rpc/java/reflect.java | 21 |
3 files changed, 121 insertions, 57 deletions
diff --git a/ext/rpc/java/README b/ext/rpc/java/README index 6c64dcfe40..097bfabf1a 100644 --- a/ext/rpc/java/README +++ b/ext/rpc/java/README @@ -22,14 +22,12 @@ What is PHP4 ext/java? 4) Exceptions raised result in PHP warnings, and null results. The warnings may be eliminated by prefixing the method call with an - "@" sign. The following experimental APIs may be used to retrieve - and reset the last error: + "@" sign. The following APIs may be used to retrieve and reset + the last error: java_last_exception_get() java_last_exception_clear() - These APIs are not currently implemented in a reentrant fashion. - 5) Overload resolution is in general a hard problem given the differences in types between the two languages. The PHP Java extension employs a simple, but fairly effective, metric for diff --git a/ext/rpc/java/java.c b/ext/rpc/java/java.c index 9d0cf7516e..83db3d4b7a 100644 --- a/ext/rpc/java/java.c +++ b/ext/rpc/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); } diff --git a/ext/rpc/java/reflect.java b/ext/rpc/java/reflect.java index 35842ea939..3cf53aece2 100644 --- a/ext/rpc/java/reflect.java +++ b/ext/rpc/java/reflect.java @@ -88,17 +88,17 @@ public class reflect { } } - static Throwable lastException = null; + Throwable lastException = null; - static void lastException(long result) { + void lastException(long result) { setResult(result, lastException); } - static void clearException() { + void clearException() { lastException = null; } - static void setException(long result, Throwable e) { + void setException(long result, Throwable e) { if (e instanceof InvocationTargetException) { Throwable t = ((InvocationTargetException)e).getTargetException(); if (t!=null) e=t; @@ -111,7 +111,7 @@ public class reflect { // // Create an new instance of a given class // - public static void CreateObject(String name, Object args[], long result) { + public void CreateObject(String name, Object args[], long result) { try { Vector matches = new Vector(); @@ -233,7 +233,7 @@ public class reflect { // // Invoke a method on a given object // - public static void Invoke + public void Invoke (Object object, String method, Object args[], long result) { @@ -281,9 +281,10 @@ public class reflect { // // Get or Set a property // - public static void GetSetProp + public void GetSetProp (Object object, String prop, Object args[], long result) { +System.out.println(object + "." + prop); try { for (Class jclass = object.getClass();;jclass=(Class)object) { @@ -340,7 +341,7 @@ public class reflect { // // Helper routines for the C implementation // - public static Object MakeArg(boolean b) { return new Boolean(b); } - public static Object MakeArg(long l) { return new Long(l); } - public static Object MakeArg(double d) { return new Double(d); } + public Object MakeArg(boolean b) { return new Boolean(b); } + public Object MakeArg(long l) { return new Long(l); } + public Object MakeArg(double d) { return new Double(d); } } |