diff --git a/apps/ivr/Ivr.cpp b/apps/ivr/Ivr.cpp index 92ab249c..9d6508a5 100644 --- a/apps/ivr/Ivr.cpp +++ b/apps/ivr/Ivr.cpp @@ -117,9 +117,20 @@ extern "C" { if(!PyArg_ParseTuple(args,"O",&py_thread_object)) return NULL; - PythonScriptThread* t = new PythonScriptThread(py_thread_object); - t->start(); - AmThreadWatcher::instance()->add(t); + IvrFactory* pIvrFactory = NULL; + PyObject *module = PyImport_ImportModule(MOD_NAME); + if (module != NULL) { + PyObject *ivrFactory = PyObject_GetAttrString(module, "__c_ivrFactory"); + if (ivrFactory != NULL){ + if (PyCObject_Check(ivrFactory)) + pIvrFactory = (IvrFactory*)PyCObject_AsVoidPtr(ivrFactory); + Py_DECREF(ivrFactory); + } + } + if (pIvrFactory) + pIvrFactory->addDeferredThread(py_thread_object); + else + ERROR("Could not find __c_ivrFactory in Python state.\n"); return Py_None; } @@ -133,13 +144,10 @@ extern "C" { } void PythonScriptThread::run() { - // PYLOCK; - // PyEval_AcquireLock(); - DBG("PythonScriptThread::run - calling python function.\n"); - + PYLOCK; + DBG("PythonScriptThread - calling python function.\n"); PyObject_CallObject(py_thread_object, NULL); - DBG("PythonScriptThread::run - thread finished..\n"); - // PyEval_ReleaseLock(); + DBG("PythonScriptThread - thread finished..\n"); } void PythonScriptThread::on_stop() { @@ -190,6 +198,10 @@ void IvrFactory::import_ivr_builtins() PyImport_AddModule("ivr"); ivr_module = Py_InitModule("ivr",ivr_methods); + PyObject* pIvrFactory = PyCObject_FromVoidPtr((void*)this,NULL); + if (pIvrFactory != NULL) + PyModule_AddObject(ivr_module, "__c_ivrFactory", pIvrFactory); + // IvrSipDialog (= AmSipDialog) import_object(ivr_module, "IvrSipDialog", &IvrSipDialogType); @@ -433,9 +445,27 @@ int IvrFactory::onLoad() } } + start_deferred_threads(); + return 0; // don't stop sems from starting up } +void IvrFactory::addDeferredThread(PyObject* pyCallable) { + deferred_threads.push(pyCallable); +} + +void IvrFactory::start_deferred_threads() { + if (!deferred_threads.empty()) { + while (!deferred_threads.empty()) { + PythonScriptThread* t = new PythonScriptThread(deferred_threads.front()); + deferred_threads.pop(); + t->start(); + AmThreadWatcher::instance()->add(t); + } + } +} + + /** * Load a script using user name from URI. * Note: there is no default script. diff --git a/apps/ivr/Ivr.h b/apps/ivr/Ivr.h index 256115e1..f0c22f64 100644 --- a/apps/ivr/Ivr.h +++ b/apps/ivr/Ivr.h @@ -98,12 +98,17 @@ class IvrFactory: public AmSessionFactory bool checkCfg(); IvrDialog* newDlg(const string& name); - + + queue deferred_threads; + void start_deferred_threads(); + public: IvrFactory(const string& _app_name); int onLoad(); AmSession* onInvite(const AmSipRequest& req); + + void addDeferredThread(PyObject* pyCallable); };