/* * Author: Henry Bruce * Copyright (c) 2016 Intel Corporation. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include #include "python/mraapy.h" // In order to call a python object (all python functions are objects) we // need to aquire the GIL (Global Interpreter Lock). This may not always be // necessary but especially if doing IO (like print()) python will segfault // if we do not hold a lock on the GIL void mraa_python_isr(void (*isr)(void*), void* isr_args) { PyGILState_STATE gilstate = PyGILState_Ensure(); PyObject* arglist; PyObject* ret; arglist = Py_BuildValue("(O)", isr_args); if (arglist == NULL) { syslog(LOG_ERR, "gpio: Py_BuildValue NULL"); } else { ret = PyEval_CallObject((PyObject*) isr, arglist); if (ret == NULL) { syslog(LOG_ERR, "gpio: PyEval_CallObject failed"); PyObject *pvalue, *ptype, *ptraceback; PyObject *pvalue_pystr, *ptype_pystr, *ptraceback_pystr; char *pvalue_cstr, *ptype_cstr, *ptraceback_cstr; PyErr_Fetch(&pvalue, &ptype, &ptraceback); pvalue_pystr = PyObject_Str(pvalue); ptype_pystr = PyObject_Str(ptype); ptraceback_pystr = PyObject_Str(ptraceback); // Python2 #if PY_VERSION_HEX < 0x03000000 pvalue_cstr = PyString_AsString(pvalue_pystr); ptype_cstr = PyString_AsString(ptype_pystr); ptraceback_cstr = PyString_AsString(ptraceback_pystr); // Python 3 and up #elif PY_VERSION_HEX >= 0x03000000 // In Python 3 we need one extra conversion PyObject *pvalue_ustr, *ptype_ustr, *ptraceback_ustr; pvalue_ustr = PyUnicode_AsUTF8String(pvalue_pystr); pvalue_cstr = PyBytes_AsString(pvalue_ustr); ptype_ustr = PyUnicode_AsUTF8String(ptype_pystr); ptype_cstr = PyBytes_AsString(ptype_ustr); ptraceback_ustr = PyUnicode_AsUTF8String(ptraceback_pystr); ptraceback_cstr = PyBytes_AsString(ptraceback_ustr); #endif // PY_VERSION_HEX syslog(LOG_ERR, "gpio: the error was %s:%s:%s", pvalue_cstr, ptype_cstr, ptraceback_cstr); Py_XDECREF(pvalue); Py_XDECREF(ptype); Py_XDECREF(ptraceback); Py_XDECREF(pvalue_pystr); Py_XDECREF(ptype_pystr); Py_XDECREF(ptraceback_pystr); // Python 3 and up #if PY_VERSION_HEX >= 0x03000000 Py_XDECREF(pvalue_ustr); Py_XDECREF(ptype_ustr); Py_XDECREF(ptraceback_ustr); #endif // PY_VERSION_HEX } else { Py_DECREF(ret); } Py_DECREF(arglist); } PyGILState_Release(gilstate); }