aboutsummaryrefslogtreecommitdiffstats
path: root/src/modules/pythoncore
diff options
context:
space:
mode:
authorGravatar Fabio Bas2009-09-24 18:12:47 +0000
committerGravatar Fabio Bas2009-09-24 18:12:47 +0000
commitf70bcc7d7b9bc71bd91e82899868bbc2f3fcd34d (patch)
tree57c2bae7ccccbb545036f073813550e1683a8f51 /src/modules/pythoncore
parentshame on me, quick fix (diff)
downloadKVIrc-f70bcc7d7b9bc71bd91e82899868bbc2f3fcd34d.tar.gz
KVIrc-f70bcc7d7b9bc71bd91e82899868bbc2f3fcd34d.tar.bz2
KVIrc-f70bcc7d7b9bc71bd91e82899868bbc2f3fcd34d.zip
some work on python module
git-svn-id: https://svn.kvirc.de/svn/trunk/kvirc@3524 17fca916-40b9-46aa-a4ea-0a15b648b75c
Diffstat (limited to 'src/modules/pythoncore')
-rw-r--r--src/modules/pythoncore/libkvipythoncore.cpp218
-rw-r--r--src/modules/pythoncore/pythoncoreinterface.h11
2 files changed, 194 insertions, 35 deletions
diff --git a/src/modules/pythoncore/libkvipythoncore.cpp b/src/modules/pythoncore/libkvipythoncore.cpp
index 49cfac429..37fa88dc0 100644
--- a/src/modules/pythoncore/libkvipythoncore.cpp
+++ b/src/modules/pythoncore/libkvipythoncore.cpp
@@ -37,54 +37,196 @@
#include "pythoncoreinterface.h"
#include <Python.h>
-/*
- class KviPythonInterpreter
+static KviKvsRunTimeContext * g_pCurrentKvsContext = 0;
+static bool g_bExecuteQuiet = false;
+static KviStr g_szLastReturnValue("");
+static QStringList g_lWarningList;
+
+static PyThreadState * mainThreadState = NULL;
+
+class KviPythonInterpreter
+{
+public:
+ KviPythonInterpreter(const QString & szContextName);
+ ~KviPythonInterpreter();
+protected:
+ QString m_szContextName;
+ PyThreadState * m_pThreadState;
+public:
+ bool init(); // if this fails then well.. :D
+ void done();
+ bool execute(const QString & szCode, QStringList & lArgs, QString & szRetVal, QString & szError, QStringList & lWarnings);
+ const QString & contextName(){ return m_szContextName; };
+};
+
+KviPythonInterpreter::KviPythonInterpreter(const QString & szContextName)
+{
+ m_szContextName = szContextName;
+ m_pThreadState = 0;
+}
+
+KviPythonInterpreter::~KviPythonInterpreter()
+{
+ done();
+}
+
+bool KviPythonInterpreter::init()
+{
+// get the global lock
+ PyEval_AcquireLock();
+ // get a reference to the PyInterpreterState
+ PyInterpreterState * mainInterpreterState = mainThreadState->interp;
+ // create a thread state object for this thread
+ m_pThreadState = PyThreadState_New(mainInterpreterState);
+ // free the lock
+ PyEval_ReleaseLock();
+ return true;
+}
+
+void KviPythonInterpreter::done()
+{
+ if(!m_pThreadState)return;
+ // grab the lock
+ PyEval_AcquireLock();
+ // swap my thread state out of the interpreter
+ PyThreadState_Swap(NULL);
+ // clear out any cruft from thread state object
+ PyThreadState_Clear(m_pThreadState);
+ // delete my thread state object
+ PyThreadState_Delete(m_pThreadState);
+ // release the lock
+ PyEval_ReleaseLock();
+ m_pThreadState = 0;
+}
+
+bool KviPythonInterpreter::execute(
+ const QString &szCode,
+ QStringList &args,
+ QString &szRetVal,
+ QString &szError,
+ QStringList &lWarnings)
+{
+ if(!m_pThreadState)
+ {
+ szError = __tr2qs_ctx("Internal error: python interpreter not initialized","python");
+ return false;
+ }
+
+ // grab the global interpreter lock
+ PyEval_AcquireLock();
+ // swap in my thread state
+ PyThreadState_Swap(m_pThreadState);
+ // execute some python code
+ PyRun_SimpleString("import sys\n");
+ PyRun_SimpleString("sys.stdout.write('Hello from a C thread!\\n')\n");
+ // clear the thread state
+ PyThreadState_Swap(NULL);
+ // release our hold on the global interpreter
+ PyEval_ReleaseLock();
+
+ return true;
+}
+
+ static KviPointerHashTable<QString,KviPythonInterpreter> * g_pInterpreters = 0;
+
+static KviPythonInterpreter * pythoncore_get_interpreter(const QString &szContextName)
+{
+ KviPythonInterpreter * i = g_pInterpreters->find(szContextName);
+ if(i)return i;
+ i = new KviPythonInterpreter(szContextName);
+ if(!i->init())
{
- public:
- KviPythonInterpreter(const QString & szContextName);
- ~KviPythonInterpreter();
- protected:
- QString m_szContextName;
- //PerlInterpreter * m_pInterpreter;
- public:
- bool init(); // if this fails then well.. :D
- void done();
- bool execute(const QString & szCode, QStringList & lArgs, QString & szRetVal, QString & szError, QStringList & lWarnings);
- const QString & contextName(){ return m_szContextName; };
- //protected:
- // QString svToQString(SV * sv);
- };
+ delete i;
+ return 0;
+ }
+ g_pInterpreters->replace(szContextName,i);
+ return i;
+}
+
+static void pythoncore_destroy_interpreter(const QString &szContextName)
+{
+ KviPythonInterpreter * i = g_pInterpreters->find(szContextName);
+ if(!i)return;
+ g_pInterpreters->remove(szContextName);
+ i->done();
+ delete i;
+}
- KviPythonInterpreter::KviPythonInterpreter(const QString & szContextName)
+static void pythoncore_destroy_all_interpreters()
+{
+ KviPointerHashTableIterator<QString,KviPythonInterpreter> it(*g_pInterpreters);
+
+ while(it.current())
{
- m_szContextName = szContextName;
- //m_pInterpreter = 0;
+ KviPythonInterpreter * i = it.current();
+ i->done();
+ delete i;
+ ++it;
}
+ g_pInterpreters->clear();
+}
- KviPythonInterpreter::~KviPythonInterpreter()
+#endif // COMPILE_PYTHON_SUPPORT
+
+static bool pythoncore_module_ctrl(KviModule *,const char * cmd,void * param)
+{
+#ifdef COMPILE_PYTHON_SUPPORT
+ if(kvi_strEqualCS(cmd,KVI_PYTHONCORECTRLCOMMAND_EXECUTE))
+ {
+ KviPythonCoreCtrlCommand_execute * ex = (KviPythonCoreCtrlCommand_execute *)param;
+ if(ex->uSize != sizeof(KviPythonCoreCtrlCommand_execute))return false;
+ g_pCurrentKvsContext = ex->pKvsContext;
+ g_bExecuteQuiet = ex->bQuiet;
+ if(ex->szContext.isEmpty())
+ {
+ KviPythonInterpreter * m = new KviPythonInterpreter("temporary");
+ if(!m->init())
+ {
+ delete m;
+ return false;
+ }
+ ex->bExitOk = m->execute(ex->szCode,ex->lArgs,ex->szRetVal,ex->szError,ex->lWarnings);
+ m->done();
+ delete m;
+ } else {
+ KviPythonInterpreter * m = pythoncore_get_interpreter(ex->szContext);
+ ex->bExitOk = m->execute(ex->szCode,ex->lArgs,ex->szRetVal,ex->szError,ex->lWarnings);
+ }
+ return true;
+ }
+ if(kvi_strEqualCS(cmd,KVI_PYTHONCORECTRLCOMMAND_DESTROY))
{
- done();
+ KviPythonCoreCtrlCommand_destroy * de = (KviPythonCoreCtrlCommand_destroy *)param;
+ if(de->uSize != sizeof(KviPythonCoreCtrlCommand_destroy))return false;
+ pythoncore_destroy_interpreter(de->szContext);
+ return true;
}
-*/
#endif // COMPILE_PYTHON_SUPPORT
+ return false;
+}
static bool pythoncore_module_init(KviModule *)
{
#ifdef COMPILE_PYTHON_SUPPORT
// Initialize the Python interpreter
- debug("Initializing Python interpreter");
#ifdef COMPILE_ON_MAC
PyMac_Initialize();
#else
Py_Initialize();
#endif
+ PyEval_InitThreads();
+
+ // save a pointer to the main PyThreadState object
+ mainThreadState = PyThreadState_Get();
+ // release the lock
+ PyEval_ReleaseLock();
// Initialize the Python module for KVIrc
- python_init();
+// python_init();
- //g_pInterpreters = new KviPointerHashTable<QString,KviPerlInterpreter>(17,false);
- //g_pInterpreters->setAutoDelete(false);
+ g_pInterpreters = new KviPointerHashTable<QString,KviPythonInterpreter>(17,false);
+ g_pInterpreters->setAutoDelete(false);
return true;
#endif // COMPILE_PYTHON_SUPPORT
@@ -95,11 +237,12 @@ static bool pythoncore_module_init(KviModule *)
static bool pythoncore_module_cleanup(KviModule *)
{
#ifdef COMPILE_PYTHON_SUPPORT
- //perlcore_destroy_all_interpreters();
- //delete g_pInterpreters;
- //g_pInterpreters = 0;
+ pythoncore_destroy_all_interpreters();
+ delete g_pInterpreters;
+ g_pInterpreters = 0;
- // Free the memory used by the Python interpreter
+ // shut down the interpreter
+ PyEval_AcquireLock();
Py_Finalize();
// Close the intepreter
@@ -109,13 +252,22 @@ static bool pythoncore_module_cleanup(KviModule *)
return true;
}
+static bool pythoncore_module_can_unload(KviModule *)
+{
+#ifdef COMPILE_PYTHON_SUPPORT
+ return (g_pInterpreters->count() == 0);
+#endif // COMPILE_PYTHON_SUPPORT
+ return true;
+}
+
KVIRC_MODULE(
"PythonCore", // module name
"4.0.0", // module version
- "Copyright (C) 2008 Elvio Basello (hellvis69 at netsons dot org", // author & (C)
+ "Copyright (C) 2008 Elvio Basello (hellvis69 at netsons dot org)\n" \
+ "Copyright (C) 2009 Fabio Bas (ctrlaltca at libero dot it)",
"Python Scripting Engine Core",
pythoncore_module_init,
- 0,
- 0,
+ pythoncore_module_can_unload,
+ pythoncore_module_ctrl,
pythoncore_module_cleanup
)
diff --git a/src/modules/pythoncore/pythoncoreinterface.h b/src/modules/pythoncore/pythoncoreinterface.h
index f09fde948..3463ce28b 100644
--- a/src/modules/pythoncore/pythoncoreinterface.h
+++ b/src/modules/pythoncore/pythoncoreinterface.h
@@ -1,5 +1,6 @@
#ifndef _PYTHONCOREINTERFACE_H_
#define _PYTHONCOREINTERFACE_H_
+
//=============================================================================
//
// File : pythoncoreinterface.h
@@ -20,7 +21,7 @@
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, write to the Free Software Foundation,
-// Inc. ,59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
//=============================================================================
@@ -30,10 +31,14 @@
#include <QStringList>
+
+#define KVI_PYTHONCORECTRLCOMMAND_EXECUTE "execute"
+
typedef struct _KviPythonCoreCtrlCommand_execute
{
unsigned int uSize;
KviKvsRunTimeContext * pKvsContext;
+ QString szContext;
QString szCode;
bool bExitOk;
QString szRetVal;
@@ -43,10 +48,12 @@ typedef struct _KviPythonCoreCtrlCommand_execute
bool bQuiet;
} KviPythonCoreCtrlCommand_execute;
+#define KVI_PYTHONCORECTRLCOMMAND_DESTROY "destroy"
+
typedef struct _KviPythonCoreCtrlCommand_destroy
{
unsigned int uSize;
QString szContext;
} KviPythonCoreCtrlCommand_destroy;
-#endif // _PYTHONCOREINTERFACE_H_
+#endif // !_PYTHONCOREINTERFACE_H_