From: Timo Korvola Date: Mon, 30 Jan 2017 14:27:13 +0000 (+0200) Subject: All getters now use GIL as well. X-Git-Tag: v1.31.0~6^2~1 X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=commitdiff_plain;h=refs%2Fchanges%2F99%2F299%2F1;p=simantics%2Fpython.git All getters now use GIL as well. More macro madness. Hopefully locking is now OK. Change-Id: I3f487cc74154574032492b9dd5c4f46b27ee7a4e --- diff --git a/org.simantics.pythonlink.win32.x86_64/jnipython.dll b/org.simantics.pythonlink.win32.x86_64/jnipython.dll index a605b4e..261bac3 100644 Binary files a/org.simantics.pythonlink.win32.x86_64/jnipython.dll and b/org.simantics.pythonlink.win32.x86_64/jnipython.dll differ diff --git a/org.simantics.pythonlink.win32.x86_64/src/sclpy.c b/org.simantics.pythonlink.win32.x86_64/src/sclpy.c index e767192..8de3c87 100644 --- a/org.simantics.pythonlink.win32.x86_64/src/sclpy.c +++ b/org.simantics.pythonlink.win32.x86_64/src/sclpy.c @@ -787,8 +787,8 @@ jobject pythonDictionaryAsMap(JNIEnv *env, PyObject *dict) { #define DEF_SETTER(typename, jtype, j2py) \ JNIEXPORT void JNICALL \ - Java_org_simantics_pythonlink_PythonContext_setPython \ - ##typename##VariableImpl( \ + Java_org_simantics_pythonlink_PythonContext_setPython##typename \ + ##VariableImpl( \ JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, \ jtype value) { \ PyObject *module = (PyObject*)contextID; \ @@ -910,269 +910,101 @@ Java_org_simantics_pythonlink_PythonContext_executePythonStatementImpl( } } -JNIEXPORT jstring JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonStringVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) { - PyObject *module = (PyObject*)contextID; - - PyObject *pythonName = getPythonString(env, variableName); - - PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName); - if (value == NULL) { - throwPythonException(env, "Python variable not found"); - return 0; - } - - if (!PyUnicode_Check(value)) { - throwPythonException(env, "Python variable not a string"); - return 0; - } - - { - jstring result = pythonStringAsJavaString(env, value); - return result; - } -} - -JNIEXPORT jobjectArray JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonStringArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) { - PyObject *module = (PyObject*)contextID; - - PyObject *pythonName = getPythonString(env, variableName); - - PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName); - if (value == NULL) { - throwPythonException(env, "Python variable not found"); - return 0; - } - - if (!PySequence_Check(value)) { - throwPythonException(env, "Python variable not a sequence"); - return 0; - } - - { - jobjectArray result = pythonSequenceAsStringArray(env, value); - return result; - } -} - -JNIEXPORT jboolean JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonBooleanVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) { - PyObject *module = (PyObject*)contextID; - - PyObject *pythonName = getPythonString(env, variableName); - - PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName); - if (value == NULL) { - throwPythonException(env, "Python variable not found"); - return 0; - } - - if (!PyBool_Check(value)) { - throwPythonException(env, "Python variable not a boolean"); - return 0; - } - - return value == Py_True; -} - -JNIEXPORT jbooleanArray JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonBooleanArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) { - PyObject *module = (PyObject*)contextID; - - PyObject *pythonName = getPythonString(env, variableName); - - PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName); - if (value == NULL) { - throwPythonException(env, "Python variable not found"); - return 0; - } - - if (!PySequence_Check(value)) { - throwPythonException(env, "Python variable not a sequence"); - return 0; - } - - { - jbooleanArray result = pythonSequenceAsBooleanArray(env, value); - return result; - } -} - -JNIEXPORT jlong JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonLongVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) { - PyObject *module = (PyObject*)contextID; - - PyObject *pythonName = getPythonString(env, variableName); - - PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName); - if (value == NULL) { - throwPythonException(env, "Python variable not found"); - return 0; - } - - if (!PyLong_Check(value)) { - throwPythonException(env, "Python variable not an integer"); - return 0; - } - - { - jlong result = PyLong_AsLongLong(value); - return result; - } -} - -JNIEXPORT jintArray JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonIntegerArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) { - PyObject *module = (PyObject*)contextID; - - PyObject *pythonName = getPythonString(env, variableName); - - PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName); - if (value == NULL) { - throwPythonException(env, "Python variable not found"); - return NULL; - } - - if (!PySequence_Check(value)) { - throwPythonException(env, "Python variable not a sequence"); - return NULL; - } - - { - jintArray result = pythonSequenceAsIntegerArray(env, value); - return result; - } -} - -JNIEXPORT jlongArray JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonLongArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) { - PyObject *module = (PyObject*)contextID; - - PyObject *pythonName = getPythonString(env, variableName); - - PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName); - if (value == NULL) { - throwPythonException(env, "Python variable not found"); - return NULL; - } - - if (!PySequence_Check(value)) { - throwPythonException(env, "Python variable not a sequence"); - return NULL; - } - { - jlongArray result = pythonSequenceAsLongArray(env, value); - return result; - } -} - -JNIEXPORT jdouble JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonDoubleVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) { - PyObject *module = (PyObject*)contextID; - - PyObject *pythonName = getPythonString(env, variableName); - - PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName); - if (value == NULL) { - throwPythonException(env, "Python variable not found"); - return 0.0; - } - - if (!PyFloat_Check(value)) { - throwPythonException(env, "Python variable not a float"); - return 0.0; - } +// Returns a borrowed reference. +static PyObject *getPythonValue( + JNIEnv *env, jlong contextID, jstring variableName) { + PyObject *module = (PyObject*)contextID; + PyObject *pythonName = getPythonString(env, variableName); + PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName); - { - jdouble result = PyFloat_AsDouble(value); - return result; - } + Py_DECREF(pythonName); + if (value == NULL) { + throwPythonException(env, "Python variable not found"); + } + return value; } -JNIEXPORT jdoubleArray JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonDoubleArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) { - PyObject *module = (PyObject*)contextID; - - PyObject *pythonName = getPythonString(env, variableName); - - PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName); - if (value == NULL) { - throwPythonException(env, "Python variable not found"); - return NULL; - } - - if (!PySequence_Check(value)) { - throwPythonException(env, "Python variable not a sequence"); - return NULL; - } - - { - jdoubleArray result = pythonSequenceAsDoubleArray(env, value); - return result; - } -} +#define DEF_GETTER(typename, jtype, check, desc, py2j) \ + JNIEXPORT jtype JNICALL \ + Java_org_simantics_pythonlink_PythonContext_getPython##typename \ + ##VariableImpl( \ + JNIEnv *env, jobject thisObj, jlong contextID, \ + jstring variableName) { \ + jtype result = 0; \ + PyEval_RestoreThread(main_ts); \ + do { \ + PyObject *value = getPythonValue(env, contextID, variableName); \ + if (value == 0) break; \ + if (check(value)) { \ + result = py2j(env, value); \ + } else { \ + throwPythonException(env, "Python variable not " desc); \ + } \ + } while (0); \ + PyEval_SaveThread(); \ + return result; \ + } -JNIEXPORT jobject JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonNDArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) { - PyObject *module = (PyObject*)contextID; +#define pythonBoolAsJboolean(env, value) ((value) == Py_True) +#define pythonLongAsJlong(env, value) PyLong_AsLongLong(value) +#define pythonFloatAsJdouble(env, value) PyFloat_AsDouble(value) + +DEF_GETTER(String, jstring, PyUnicode_Check, "a string", + pythonStringAsJavaString) +DEF_GETTER(StringArray, jobjectArray, PySequence_Check, "a sequence", + pythonSequenceAsStringArray) +DEF_GETTER(Boolean, jboolean, PyBool_Check, "a Boolean", pythonBoolAsJboolean) +DEF_GETTER(BooleanArray, jbooleanArray, PySequence_Check, "a sequence", + pythonSequenceAsBooleanArray) +DEF_GETTER(Long, jlong, PyLong_Check, "an integer", pythonLongAsJlong) +DEF_GETTER(IntegerArray, jintArray, PySequence_Check, "a sequence", + pythonSequenceAsIntegerArray) +DEF_GETTER(LongArray, jlongArray, PySequence_Check, "a sequence", + pythonSequenceAsLongArray) +DEF_GETTER(Double, jdouble, PyFloat_Check, "a float", pythonFloatAsJdouble) +DEF_GETTER(DoubleArray, jdoubleArray, PySequence_Check, "a sequence", + pythonSequenceAsDoubleArray) + +JNIEXPORT jobject JNICALL +Java_org_simantics_pythonlink_PythonContext_getPythonNDArrayVariableImpl( + JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) { + jobject result = NULL; if (!hasNumpy) { throwPythonException(env, "Importing numpy failed"); return NULL; } - { - PyObject *pythonName = getPythonString(env, variableName); - - PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName); - if (value == NULL) { - throwPythonException(env, "Python variable not found"); - return NULL; - } - + PyEval_RestoreThread(main_ts); + do { + PyObject *value = getPythonValue(env, contextID, variableName); + if (value == NULL) break; if (!PyArray_Check(value)) { throwPythonException(env, "Python variable not an ndarray"); - return NULL; - } - - if (PyArray_TYPE((PyArrayObject*)value) != NPY_DOUBLE) { - throwPythonException(env, "Only ndarrays of type double are supported"); - return NULL; + } else if (PyArray_TYPE((PyArrayObject*)value) != NPY_DOUBLE) { + throwPythonException( + env, "Only ndarrays of type double are supported"); + } else { + result = pythonArrayAsNDArray(env, (PyArrayObject *)value); } - - { - jobject result = pythonArrayAsNDArray(env, (PyArrayObject *)value); - return result; - } - } -} - -JNIEXPORT jobject JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonVariantVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) { - PyObject *module = (PyObject*)contextID; - - PyObject *pythonName = getPythonString(env, variableName); - - PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName); - if (value == NULL) { - throwPythonException(env, "Python variable not found"); - return NULL; - } - - hasNumpy = _import_array() != -1; - - { - jobject result = pythonObjectAsObject(env, value); - return result; - } + } while (0); + PyEval_SaveThread(); + return result; } -JNIEXPORT jint JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonVariableTypeImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) { - PyObject *module = (PyObject*)contextID; - PyObject *dict = PyModule_GetDict(module); +#define python_anything_goes(value) 1 - PyObject *pythonName = getPythonString(env, variableName); - - if (!PyDict_Contains(dict, pythonName)) { - return 0; - } +DEF_GETTER(Variant, jobject, python_anything_goes, "frabjous", + pythonObjectAsObject) +JNIEXPORT jint JNICALL +Java_org_simantics_pythonlink_PythonContext_getPythonVariableTypeImpl( + JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) { + jint result = 0; + PyEval_RestoreThread(main_ts); { - PyObject *value = PyDict_GetItem(dict, pythonName); - - jint result; - + PyObject *value = getPythonValue(env, contextID, variableName); if (PyBool_Check(value)) result = 1; else if (PyLong_Check(value)) @@ -1191,28 +1023,36 @@ JNIEXPORT jint JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonVari result = 8; else result = -1; - - return result; } + PyEval_SaveThread(); + return result; } -JNIEXPORT jobjectArray JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonVariableNamesImpl(JNIEnv *env, jobject thisObj, jlong contextID) { - PyObject *module = (PyObject*)contextID; - PyObject *dict = PyModule_GetDict(module); +JNIEXPORT jobjectArray JNICALL +Java_org_simantics_pythonlink_PythonContext_getPythonVariableNamesImpl( + JNIEnv *env, jobject thisObj, jlong contextID) { + jobjectArray result = NULL; + PyEval_RestoreThread(main_ts); + { + PyObject *module = (PyObject*)contextID; + PyObject *dict = PyModule_GetDict(module); - PyObject *keys = PyDict_Keys(dict); - Py_ssize_t size = PyList_Size(keys); + PyObject *keys = PyDict_Keys(dict); + Py_ssize_t size = PyList_Size(keys); + Py_ssize_t i; - jobjectArray result = (*env)->NewObjectArray(env, (jsize)size, (*env)->FindClass(env, STRING_CLASS), NULL); + result = (*env)->NewObjectArray( + env, (jsize)size, (*env)->FindClass(env, STRING_CLASS), NULL); - Py_ssize_t i; - for (i = 0; i < size; i++) { - jstring javaName = pythonStringAsJavaString(env, PyList_GetItem(keys, i)); - (*env)->SetObjectArrayElement(env, result, (jint)i, javaName); - } - - Py_XDECREF(keys); + for (i = 0; i < size; i++) { + jstring javaName = pythonStringAsJavaString( + env, PyList_GetItem(keys, i)); + (*env)->SetObjectArrayElement(env, result, (jint)i, javaName); + } + Py_XDECREF(keys); + } + PyEval_SaveThread(); return result; }