summaryrefslogtreecommitdiff
path: root/numpy/f2py/src/fortranobject.c
diff options
context:
space:
mode:
authorPauli Virtanen <pav@iki.fi>2020-06-07 15:37:21 +0300
committerPauli Virtanen <pav@iki.fi>2020-06-07 21:27:50 +0300
commitc3491aa1a6458e6cc1fce72dd9e0ec6e05e7c911 (patch)
treeea31542fec06e0b5f675e32d2c641939ff538a7e /numpy/f2py/src/fortranobject.c
parent267621f07a902eceffc179fa01f984f3e2d4bdcd (diff)
downloadnumpy-c3491aa1a6458e6cc1fce72dd9e0ec6e05e7c911.tar.gz
BUG: numpy/f2py: put callback globals to thread-local storage
Diffstat (limited to 'numpy/f2py/src/fortranobject.c')
-rw-r--r--numpy/f2py/src/fortranobject.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/numpy/f2py/src/fortranobject.c b/numpy/f2py/src/fortranobject.c
index b3a04bcf0..aa46c57d0 100644
--- a/numpy/f2py/src/fortranobject.c
+++ b/numpy/f2py/src/fortranobject.c
@@ -30,6 +30,68 @@ F2PyDict_SetItemString(PyObject *dict, char *name, PyObject *obj)
return PyDict_SetItemString(dict, name, obj);
}
+/*
+ * Python-only fallback for thread-local callback pointers
+ */
+void *F2PySwapThreadLocalCallbackPtr(char *key, void *ptr)
+{
+ PyObject *local_dict, *value;
+ void *prev;
+
+ local_dict = PyThreadState_GetDict();
+ if (local_dict == NULL) {
+ Py_FatalError("F2PySwapThreadLocalCallbackPtr: PyThreadState_GetDict failed");
+ }
+
+ value = PyDict_GetItemString(local_dict, key);
+ if (value != NULL) {
+ prev = PyLong_AsVoidPtr(value);
+ if (PyErr_Occurred()) {
+ Py_FatalError("F2PySwapThreadLocalCallbackPtr: PyLong_AsVoidPtr failed");
+ }
+ }
+ else {
+ prev = NULL;
+ }
+
+ value = PyLong_FromVoidPtr((void *)ptr);
+ if (value == NULL) {
+ Py_FatalError("F2PySwapThreadLocalCallbackPtr: PyLong_FromVoidPtr failed");
+ }
+
+ if (PyDict_SetItemString(local_dict, key, value) != 0) {
+ Py_FatalError("F2PySwapThreadLocalCallbackPtr: PyDict_SetItemString failed");
+ }
+
+ Py_DECREF(value);
+
+ return prev;
+}
+
+void *F2PyGetThreadLocalCallbackPtr(char *key)
+{
+ PyObject *local_dict, *value;
+ void *prev;
+
+ local_dict = PyThreadState_GetDict();
+ if (local_dict == NULL) {
+ Py_FatalError("F2PyGetThreadLocalCallbackPtr: PyThreadState_GetDict failed");
+ }
+
+ value = PyDict_GetItemString(local_dict, key);
+ if (value != NULL) {
+ prev = PyLong_AsVoidPtr(value);
+ if (PyErr_Occurred()) {
+ Py_FatalError("F2PyGetThreadLocalCallbackPtr: PyLong_AsVoidPtr failed");
+ }
+ }
+ else {
+ prev = NULL;
+ }
+
+ return prev;
+}
+
/************************* FortranObject *******************************/
typedef PyObject *(*fortranfunc)(PyObject *,PyObject *,PyObject *,void *);