From 5dab6232ef3b3715630cf88eb40c4c6021e65f07 Mon Sep 17 00:00:00 2001 From: Michele Calgaro Date: Fri, 14 Oct 2022 18:20:15 +0900 Subject: superkaramba: fixed SEGV when loading python scripts. This resolves issue #43. Signed-off-by: Michele Calgaro --- superkaramba/src/karamba.cpp | 7 ++- superkaramba/src/karamba_python.cpp | 87 +++++-------------------------------- superkaramba/src/karamba_python.h | 4 +- 3 files changed, 16 insertions(+), 82 deletions(-) (limited to 'superkaramba') diff --git a/superkaramba/src/karamba.cpp b/superkaramba/src/karamba.cpp index 19b30b5..f9e3e76 100644 --- a/superkaramba/src/karamba.cpp +++ b/superkaramba/src/karamba.cpp @@ -310,7 +310,7 @@ karamba::karamba(TQString fn, TQString name, bool reloading, int instance, move(xpos, ypos); } - haveUpdated = 0; + haveUpdated = false; this->setMouseTracking(true); @@ -1691,14 +1691,13 @@ void karamba::step() if (pythonIface && pythonIface->isExtensionLoaded()) { - if (haveUpdated == 0) + if (!haveUpdated) pythonIface->initWidget(this); else pythonIface->widgetUpdated(this); } - if (haveUpdated == 0) - haveUpdated = 1; + haveUpdated = true; } void karamba::widgetClosed() diff --git a/superkaramba/src/karamba_python.cpp b/superkaramba/src/karamba_python.cpp index 73212a0..97bb228 100644 --- a/superkaramba/src/karamba_python.cpp +++ b/superkaramba/src/karamba_python.cpp @@ -51,12 +51,7 @@ struct module_state { PyObject *error; }; -#if PY_MAJOR_VERSION >= 3 #define GETSTATE(m) ((struct module_state*)PyModule_GetState(m)) -#else -#define GETSTATE(m) (&_state) -static struct module_state _state; -#endif static PyObject * error_out(PyObject *m) { @@ -356,8 +351,6 @@ static PyMethodDef karamba_methods[] = { {NULL, NULL, 0 ,NULL} }; -#if PY_MAJOR_VERSION >= 3 - static int karamba_traverse(PyObject *m, visitproc visit, void *arg) { Py_VISIT(GETSTATE(m)->error); return 0; @@ -382,22 +375,18 @@ static struct PyModuleDef karambadef = { #define INITERROR return NULL -#else - -#define INITERROR return - -#endif +PyMODINIT_FUNC PyInit_karamba(void) +{ + return PyModule_Create(&karambadef); +} PyThreadState* KarambaPython::mainThreadState = 0; KarambaPython::KarambaPython(const ThemeFile& theme, bool reloading): pythonThemeExtensionLoaded(false), pName(0), pModule(0), pDict(0) { - PyThreadState* myThreadState; char pypath[1024]; - getLock(&myThreadState); - // load the .py file for this .theme PyRun_SimpleString((char*)"import sys"); //Add theme path to python path so that we can find the python file @@ -405,13 +394,7 @@ KarambaPython::KarambaPython(const ThemeFile& theme, bool reloading): PyRun_SimpleString(pypath); PyRun_SimpleString((char*)"sys.path.insert(0, '')"); - PyImport_AddModule((char*)"karamba"); -#if PY_MAJOR_VERSION >= 3 - PyModule_Create(&karambadef); -#else - Py_InitModule((char*)"karamba", karamba_methods); -#endif - pName = PyBytes_FromString(theme.pythonModule().ascii()); + pName = PyUnicode_FromString(theme.pythonModule().utf8()); pModule = PyImport_Import(pName); fprintf(stderr, "%s\n", pypath); @@ -443,72 +426,40 @@ KarambaPython::KarambaPython(const ThemeFile& theme, bool reloading): fprintf(stderr, "------------------------------------------------------\n"); } - releaseLock(myThreadState); } KarambaPython::~KarambaPython() { //Clean up Python references if (pythonThemeExtensionLoaded) { - PyThreadState* myThreadState; - getLock(&myThreadState); - //Displose of current python module so we can reload in constructor. Py_DECREF(pModule); Py_DECREF(pName); - - releaseLock(myThreadState); } } void KarambaPython::initPython() { // initialize Python + PyImport_AppendInittab((char*)"karamba", PyInit_karamba); Py_Initialize(); +#if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION <= 6 // initialize thread support PyEval_InitThreads(); +#endif // save a pointer to the main PyThreadState object mainThreadState = PyThreadState_Get(); - - // release the lock - PyEval_ReleaseLock(); } void KarambaPython::shutdownPython() { // shut down the interpreter - PyInterpreterState * mainInterpreterState = mainThreadState->interp; - // create a thread state object for this thread - PyThreadState * myThreadState = PyThreadState_New(mainInterpreterState); - PyThreadState_Swap(myThreadState); - PyEval_AcquireLock(); + PyThreadState_Swap(mainThreadState); Py_Finalize(); } -void KarambaPython::getLock(PyThreadState** myThreadState) -{ - // get the global lock - PyEval_AcquireLock(); - - // create a thread state object for this thread - *myThreadState = PyThreadState_New(mainThreadState->interp); - PyThreadState_Swap(*myThreadState); -} - -void KarambaPython::releaseLock(PyThreadState* myThreadState) -{ - // swap my thread state out of the interpreter - PyThreadState_Swap(NULL); - // clear out any cruft from thread state object - PyThreadState_Clear(myThreadState); - // delete my thread state object - PyThreadState_Delete(myThreadState); - // release the lock - PyEval_ReleaseLock(); -} - PyObject* KarambaPython::getFunc(const char* function) { PyObject* pFunc = PyDict_GetItemString(pDict, (char*)function); @@ -517,17 +468,11 @@ PyObject* KarambaPython::getFunc(const char* function) return NULL; } -bool KarambaPython::callObject(const char* func, PyObject* pArgs, bool lock) +bool KarambaPython::callObject(const char* func, PyObject* pArgs) { bool result = false; - PyThreadState* myThreadState; - //tqDebug("Calling %s", func); - - if (lock) - getLock(&myThreadState); PyObject* pFunc = getFunc(func); - if (pFunc != NULL) { PyObject* pValue = PyObject_CallObject(pFunc, pArgs); @@ -544,8 +489,6 @@ bool KarambaPython::callObject(const char* func, PyObject* pArgs, bool lock) } } Py_DECREF(pArgs); - if (lock) - releaseLock(myThreadState); return result; } @@ -597,8 +540,7 @@ bool KarambaPython::widgetClicked(karamba* k, int x, int y, int button) return callObject("widgetClicked", pArgs); } -bool KarambaPython::keyPressed(karamba* k, const Meter* meter, - const TQString& text) +bool KarambaPython::keyPressed(karamba* k, const Meter* meter, const TQString& text) { PyObject* pArgs = Py_BuildValue((char*)"(lls)", k, meter, text.ucs2()); return callObject("keyPressed", pArgs); @@ -660,13 +602,8 @@ bool KarambaPython::itemDropped(karamba* k, TQString text, int x, int y) bool KarambaPython::themeNotify(karamba* k, const char *from, const char *str) { - // WARNING WARNING WARNING i had to switch off thread locking to get - // this to work. callNotify is called from INSIDE another locked thread, - // so can never complete because themeNotify will expect locking to be - // released... - // PyObject* pArgs = Py_BuildValue((char*)"(lss)", k, from, str); - return callObject("themeNotify", pArgs, false); + return callObject("themeNotify", pArgs); } bool KarambaPython::systrayUpdated(karamba* k) diff --git a/superkaramba/src/karamba_python.h b/superkaramba/src/karamba_python.h index b3f7a0a..5227d6d 100644 --- a/superkaramba/src/karamba_python.h +++ b/superkaramba/src/karamba_python.h @@ -45,10 +45,8 @@ protected: PyObject *pDict; static PyThreadState* mainThreadState; - void getLock(PyThreadState** myThreadState); PyObject* getFunc(const char* function); - void releaseLock(PyThreadState* myThreadState); - bool callObject(const char* func, PyObject* pArgs, bool lock=true); + bool callObject(const char* func, PyObject* pArgs); public: KarambaPython(const ThemeFile& theme, bool reloading); -- cgit v1.2.1