From 8f2ce8e703daeced896cab3389a5e8329ecd958d Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Thu, 14 Feb 2013 16:43:58 +0100 Subject: [PATCH] Implemented rudimentary function call forwarding for ScriptInterpreter objects. --- lib/base/scriptinterpreter.cpp | 40 ++++++++++++++++++++++++++------ lib/base/scriptinterpreter.h | 17 +++++++++----- lib/python/pythoninterpreter.cpp | 29 +++++++++++++++++++---- lib/python/pythoninterpreter.h | 7 +++++- 4 files changed, 74 insertions(+), 19 deletions(-) diff --git a/lib/base/scriptinterpreter.cpp b/lib/base/scriptinterpreter.cpp index 028edbed1..61065609b 100644 --- a/lib/base/scriptinterpreter.cpp +++ b/lib/base/scriptinterpreter.cpp @@ -40,6 +40,8 @@ void ScriptInterpreter::Start(void) void ScriptInterpreter::Stop(void) { + assert(Application::IsMainThread()); + { boost::mutex::scoped_lock lock(m_Mutex); @@ -50,6 +52,10 @@ void ScriptInterpreter::Stop(void) m_CallAvailable.notify_all(); } + BOOST_FOREACH(const String& function, m_SubscribedFunctions) { + ScriptFunction::Unregister(function); + } + m_Thread.join(); } @@ -69,15 +75,35 @@ void ScriptInterpreter::ThreadWorkerProc(void) } } - -void ScriptInterpreter::EnqueueCall(const ScriptCall& call) +void ScriptInterpreter::ScriptFunctionThunk(const ScriptTask::Ptr& task, + const vector& arguments, const String& function) { - boost::mutex::scoped_lock lock(m_Mutex); - m_Calls.push_back(call); - m_CallAvailable.notify_all(); + ScriptCall call; + call.Function = function; + call.Arguments = arguments; + call.Task = task; + + { + boost::mutex::scoped_lock lock(m_Mutex); + m_Calls.push_back(call); + m_CallAvailable.notify_all(); + } } -void ScriptInterpreter::RegisterMethod(const String& name) +void ScriptInterpreter::SubscribeFunction(const String& name) { - // TODO: implement + assert(Application::IsMainThread()); + + m_SubscribedFunctions.insert(name); + + ScriptFunction::Ptr sf = boost::make_shared(boost::bind(&ScriptInterpreter::ScriptFunctionThunk, this, _1, _2, name)); + ScriptFunction::Register(name, sf); +} + +void ScriptInterpreter::UnsubscribeFunction(const String& name) +{ + assert(Application::IsMainThread()); + + m_SubscribedFunctions.erase(name); + ScriptFunction::Unregister(name); } diff --git a/lib/base/scriptinterpreter.h b/lib/base/scriptinterpreter.h index a207376dd..e7f22b208 100644 --- a/lib/base/scriptinterpreter.h +++ b/lib/base/scriptinterpreter.h @@ -25,8 +25,8 @@ namespace icinga struct ScriptCall { - String Method; - vector Arguments; + String Function; + vector Arguments; ScriptTask::Ptr Task; }; @@ -43,17 +43,17 @@ public: ~ScriptInterpreter(void); - void EnqueueCall(const ScriptCall& call); - void Start(void); void Stop(void); protected: ScriptInterpreter(const Script::Ptr& script); - virtual void ProcessCall(const ScriptCall& call) = 0; + virtual void ProcessCall(const String& function, const ScriptTask::Ptr& task, + const vector& arguments) = 0; - void RegisterMethod(const String& name); + void SubscribeFunction(const String& name); + void UnsubscribeFunction(const String& name); private: boost::mutex m_Mutex; @@ -61,9 +61,14 @@ private: deque m_Calls; condition_variable m_CallAvailable; + set m_SubscribedFunctions; /* Not protected by the mutex. */ + boost::thread m_Thread; void ThreadWorkerProc(void); + + void ScriptFunctionThunk(const ScriptTask::Ptr& task, + const vector& arguments, const String& function); }; } diff --git a/lib/python/pythoninterpreter.cpp b/lib/python/pythoninterpreter.cpp index d56bdff91..4c48735ba 100644 --- a/lib/python/pythoninterpreter.cpp +++ b/lib/python/pythoninterpreter.cpp @@ -21,7 +21,8 @@ using namespace icinga; -PythonInterpreter::PythonInterpreter(const PythonLanguage::Ptr& language, const Script::Ptr& script) +PythonInterpreter::PythonInterpreter(const PythonLanguage::Ptr& language, + const Script::Ptr& script) : ScriptInterpreter(script), m_Language(language), m_ThreadState(NULL) { PyEval_AcquireLock(); @@ -31,9 +32,11 @@ PythonInterpreter::PythonInterpreter(const PythonLanguage::Ptr& language, const (void) PyThreadState_Swap(m_ThreadState); PyRun_SimpleString(script->GetCode().CStr()); - (void) PyThreadState_Swap(m_Language->GetMainThreadState()); + (void) PyThreadState_Swap(NULL); PyEval_ReleaseLock(); + + SubscribeFunction("python::Test"); } PythonInterpreter::~PythonInterpreter(void) @@ -48,11 +51,27 @@ PythonInterpreter::~PythonInterpreter(void) PyEval_ReleaseLock(); } -void PythonInterpreter::ProcessCall(const ScriptCall& call) +void PythonInterpreter::RegisterFunction(const String& name, PyObject *function) +{ + SubscribeFunction(name); + + Py_INCREF(function); + m_Functions[name] = function; +} + +void PythonInterpreter::UnregisterFunction(const String& name) +{ + UnsubscribeFunction(name); + + m_Functions.erase(name); +} + +void PythonInterpreter::ProcessCall(const String& function, const ScriptTask::Ptr& task, + const vector& arguments) { PyEval_AcquireThread(m_ThreadState); - PyRun_SimpleString("import antigravity"); + std::cout << "Received call for method '" << function << "'" << std::endl; PyEval_ReleaseThread(m_ThreadState); - call.Task->FinishResult(0); + task->FinishResult(0); } diff --git a/lib/python/pythoninterpreter.h b/lib/python/pythoninterpreter.h index 70d19ef88..73892c2f1 100644 --- a/lib/python/pythoninterpreter.h +++ b/lib/python/pythoninterpreter.h @@ -37,11 +37,16 @@ public: PythonInterpreter(const PythonLanguage::Ptr& language, const Script::Ptr& script); ~PythonInterpreter(void); + void RegisterFunction(const String& name, PyObject *function); + void UnregisterFunction(const String& name); + protected: PythonLanguage::Ptr m_Language; PyThreadState *m_ThreadState; + map m_Functions; - virtual void ProcessCall(const ScriptCall& call); + virtual void ProcessCall(const String& function, const ScriptTask::Ptr& task, + const vector& arguments); }; }