diff options
author | Pauli Virtanen <pav@iki.fi> | 2020-06-07 15:37:21 +0300 |
---|---|---|
committer | Pauli Virtanen <pav@iki.fi> | 2020-06-07 21:27:50 +0300 |
commit | c3491aa1a6458e6cc1fce72dd9e0ec6e05e7c911 (patch) | |
tree | ea31542fec06e0b5f675e32d2c641939ff538a7e /numpy/f2py/src/fortranobject.c | |
parent | 267621f07a902eceffc179fa01f984f3e2d4bdcd (diff) | |
download | numpy-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.c | 62 |
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 *); |