Author: sayer
Date: 2009-05-08 15:26:05 +0200 (Fri, 08 May 2009)
New Revision: 1374
Modified:
trunk/apps/dsm/mods/mod_py/ModPy.cpp
trunk/apps/dsm/mods/mod_py/ModPy.h
Log:
* simplified code
* does not crash any more (TM): threads are initialized
* needs preload
* still leaks ~1k/call
Modified: trunk/apps/dsm/mods/mod_py/ModPy.cpp
===================================================================
--- trunk/apps/dsm/mods/mod_py/ModPy.cpp 2009-05-08 08:10:05 UTC (rev
1373)
+++ trunk/apps/dsm/mods/mod_py/ModPy.cpp 2009-05-08 13:26:05 UTC (rev
1374)
@@ -49,11 +49,20 @@
PyObject* SCPyModule::session_module = NULL;
SCPyModule::SCPyModule() {
+
+}
+
+SCPyModule::~SCPyModule() {
+}
+
+int SCPyModule::preload() {
if(!Py_IsInitialized()){
Py_Initialize();
DBG("Python version %s\n", Py_GetVersion());
}
+ PyEval_InitThreads();
+
PyImport_AddModule("dsm");
dsm_module = Py_InitModule("dsm",mod_py_methods);
PyModule_AddIntConstant(dsm_module, "Any", DSMCondition::Any);
@@ -63,8 +72,7 @@
PyModule_AddIntConstant(dsm_module, "Timer", DSMCondition::Timer);
PyModule_AddIntConstant(dsm_module, "NoAudio", DSMCondition::NoAudio);
PyModule_AddIntConstant(dsm_module, "Hangup", DSMCondition::Hangup);
- PyModule_AddIntConstant(dsm_module, "Hold", DSMCondition::Hold);
- PyModule_AddIntConstant(dsm_module, "UnHold", DSMCondition::UnHold);
+ PyModule_AddIntConstant(dsm_module, "Hold", DSMCondition::Hold);
PyModule_AddIntConstant(dsm_module, "UnHold", DSMCondition::UnHold);
PyModule_AddIntConstant(dsm_module, "XmlrpcResponse",
DSMCondition::XmlrpcResponse);
PyModule_AddIntConstant(dsm_module, "DSMEvent", DSMCondition::DSMEvent);
PyModule_AddIntConstant(dsm_module, "PlaylistSeparator",
DSMCondition::PlaylistSeparator);
@@ -73,19 +81,29 @@
PyImport_AddModule("session");
session_module = Py_InitModule("session",session_methods);
-}
-SCPyModule::~SCPyModule() {
+ PyEval_ReleaseLock();
+ return 0;
+// _thr_state = PyEval_SaveThread();
}
-
DSMAction* SCPyModule::getAction(const string& from_str) {
string cmd;
string params;
splitCmd(from_str, cmd, params);
- DEF_CMD("py", SCPyPyAction);
+ if (NULL==dsm_module) {
+ ERROR("mod_py must be preloaded! add preload=mod_py to dsm.conf\n");
+ return NULL;
+ }
+ try {
+ DEF_CMD("py", SCPyPyAction);
+ } catch (const string& err) {
+ ERROR("creating py() action\n");
+ return NULL;
+ }
+
return NULL;
}
@@ -94,29 +112,31 @@
string params;
splitCmd(from_str, cmd, params);
+ if (NULL==dsm_module) {
+ ERROR("mod_py must be preloaded! add preload=mod_py to dsm.conf\n");
+ return NULL;
+ }
+
if (cmd == "py") {
- return new PyPyCondition(params);
+ try {
+ return new PyPyCondition(params);
+ } catch (const string& err) {
+ ERROR("creating py() condition\n");
+ return NULL;
+ }
}
return NULL;
}
-SCPyPyAction::SCPyPyAction(const string& arg) {
- py_func = Py_CompileString(arg.c_str(), "<mod_py>", Py_file_input);
- if (NULL == py_func) {
- ERROR("compiling python code '%s'\n",
- arg.c_str());
- if(PyErr_Occurred())
- PyErr_Print();
+bool py_execute(PyCodeObject* py_func, DSMSession* sc_sess,
+ DSMCondition::EventType event, map<string,string>* event_params,
+ bool expect_int_result) {
+ // acquire the GIL
+ PYLOCK;
- throw string("compiling python code '" + arg +"'");
- }
-}
-
-EXEC_ACTION_START(SCPyPyAction) {
- // do we need to acquire the lock? but it crashes...
- // PYLOCK;
-
+ bool py_res = false;
+
PyObject* m = PyImport_AddModule("__main__");
if (m == NULL) {
ERROR("getting main module\n");
@@ -125,14 +145,15 @@
PyObject*d = PyModule_GetDict(m);
PyObject* locals = PyDict_New();
- PyDict_SetItemString(locals, "dsm", SCPyModule::dsm_module);
- PyDict_SetItemString(locals, "session", SCPyModule::session_module);
+ PyDict_SetItem(locals, PyString_FromString("dsm"), SCPyModule::dsm_module);
+ PyDict_SetItem(locals, PyString_FromString("session"),
SCPyModule::session_module);
PyObject* params = PyDict_New();
if (NULL != event_params) {
for (map<string,string>::iterator it=event_params->begin();
it != event_params->end(); it++) {
- PyDict_SetItemString(params, it->first.c_str(),
PyString_FromString(it->second.c_str()));
+ PyDict_SetItemString(params, it->first.c_str(),
+ PyString_FromString(it->second.c_str()));
}
}
PyDict_SetItemString(locals, "params", params);
@@ -142,32 +163,35 @@
PyObject* ts_dict = PyThreadState_GetDict();
PyDict_SetItemString(ts_dict, "_dsm_sess_", py_sc_sess);
-
// call the function
PyObject* res = PyEval_EvalCode((PyCodeObject*)py_func, d, locals);
-
- if(PyErr_Occurred()){
- PyErr_Print();
- }
+ if(PyErr_Occurred())
+ PyErr_Print();
+
ts_dict = PyThreadState_GetDict(); // should be the same as before
py_sc_sess = PyDict_GetItemString(ts_dict, "_dsm_sess_"); // should be the
same as before
- Py_XDECREF(py_sc_sess);
-
+ Py_XDECREF(py_sc_sess);
PyDict_DelItemString(ts_dict, "_dsm_sess_");
+ Py_DECREF(params);
Py_DECREF(locals);
if (NULL == res) {
ERROR("evaluating python code\n");
+ } else if (PyBool_Check(res)) {
+ py_res = PyInt_AsLong(res);
} else {
- Py_XDECREF(res);
+ if (expect_int_result) {
+ ERROR("unknown result from python code\n");
+ }
+ Py_DECREF(res);
}
-} EXEC_ACTION_END;
+ return py_res;
+}
-
-PyPyCondition::PyPyCondition(const string& arg) {
- py_func = Py_CompileString(arg.c_str(), "<mod_py>", Py_eval_input);
+SCPyPyAction::SCPyPyAction(const string& arg) {
+ py_func = Py_CompileString(arg.c_str(), "<mod_py>", Py_file_input);
if (NULL == py_func) {
ERROR("compiling python code '%s'\n",
arg.c_str());
@@ -178,57 +202,26 @@
}
}
-MATCH_CONDITION_START(PyPyCondition) {
- // probably we need to acquire the lock? but it crashes..
- // PYLOCK;
+EXEC_ACTION_START(SCPyPyAction) {
+ py_execute((PyCodeObject*)py_func, sc_sess,
+ event, event_params, false);
- bool cond_res = false;
-
- PyObject* m = PyImport_AddModule("__main__");
- if (m == NULL) {
- ERROR("getting main module\n");
- return false;
- }
- PyObject*d = PyModule_GetDict(m);
+} EXEC_ACTION_END;
- PyObject* locals = PyDict_New();
- PyDict_SetItem(locals, PyString_FromString("dsm"), SCPyModule::dsm_module);
- PyDict_SetItem(locals, PyString_FromString("session"),
SCPyModule::session_module);
- PyObject* params = PyDict_New();
- if (NULL != event_params) {
- for (map<string,string>::iterator it=event_params->begin();
- it != event_params->end(); it++) {
- PyDict_SetItemString(params, it->first.c_str(),
PyString_FromString(it->second.c_str()));
- }
- }
- PyDict_SetItemString(locals, "params", params);
- PyDict_SetItemString(locals, "type", PyInt_FromLong(event));
+PyPyCondition::PyPyCondition(const string& arg) {
+ py_func = Py_CompileString(arg.c_str(), "<mod_py>", Py_eval_input);
+ if (NULL == py_func) {
+ ERROR("compiling python code '%s'\n",
+ arg.c_str());
+ if(PyErr_Occurred())
+ PyErr_Print();
- PyObject* py_sc_sess = PyCObject_FromVoidPtr(sc_sess,NULL);
- PyObject* ts_dict = PyThreadState_GetDict();
- PyDict_SetItemString(ts_dict, "_dsm_sess_", py_sc_sess);
-
- // call the function
- PyObject* res = PyEval_EvalCode((PyCodeObject*)py_func, d, locals);
-
- if(PyErr_Occurred())
- PyErr_Print();
-
- ts_dict = PyThreadState_GetDict(); // should be the same as before
- py_sc_sess = PyDict_GetItemString(ts_dict, "_dsm_sess_"); // should be the
same as before
- Py_XDECREF(py_sc_sess);
-
- PyDict_DelItemString(ts_dict, "_dsm_sess_");
-
- Py_DECREF(locals);
- if (NULL == res) {
- ERROR("evaluating python code\n");
- } else if (PyBool_Check(res)) {
- cond_res = PyInt_AsLong(res);
- } else {
- ERROR("unknown result from python code\n");
+ throw string("compiling python code '" + arg +"'");
}
+}
- return cond_res;
+MATCH_CONDITION_START(PyPyCondition) {
+ return py_execute((PyCodeObject*)py_func, sc_sess,
+ event, event_params, false);
} MATCH_CONDITION_END;
Modified: trunk/apps/dsm/mods/mod_py/ModPy.h
===================================================================
--- trunk/apps/dsm/mods/mod_py/ModPy.h 2009-05-08 08:10:05 UTC (rev 1373)
+++ trunk/apps/dsm/mods/mod_py/ModPy.h 2009-05-08 13:26:05 UTC (rev 1374)
@@ -37,9 +37,12 @@
public:
+
SCPyModule();
~SCPyModule();
+ int preload();
+
DSMAction* getAction(const string& from_str);
DSMCondition* getCondition(const string& from_str);
static PyObject* dsm_module;
_______________________________________________
Semsdev mailing list
[email protected]
http://lists.iptel.org/mailman/listinfo/semsdev