superkaramba: fixed SEGV when loading python scripts.

This resolves issue #43.

Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
pull/44/head
Michele Calgaro 2 years ago
parent 2e211499d4
commit 5dab6232ef
Signed by: MicheleC
GPG Key ID: 2A75B7CA8ADED5CF

@ -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()

@ -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)

@ -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);

Loading…
Cancel
Save