]> granicus.if.org Git - icinga2/commitdiff
Implemented rudimentary function call forwarding for ScriptInterpreter objects.
authorGunnar Beutner <gunnar.beutner@netways.de>
Thu, 14 Feb 2013 15:43:58 +0000 (16:43 +0100)
committerGunnar Beutner <gunnar.beutner@netways.de>
Thu, 14 Feb 2013 15:47:36 +0000 (16:47 +0100)
lib/base/scriptinterpreter.cpp
lib/base/scriptinterpreter.h
lib/python/pythoninterpreter.cpp
lib/python/pythoninterpreter.h

index 028edbed15918fa967a9d6b5ccbedb08e5e4fe2f..61065609b78391ba9a50530cee64d126fd891df6 100644 (file)
@@ -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::ScriptFunctionThunk(const ScriptTask::Ptr& task,
+    const vector<Value>& arguments, const String& function)
+{
+       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::EnqueueCall(const ScriptCall& call)
+void ScriptInterpreter::SubscribeFunction(const String& name)
 {
-       boost::mutex::scoped_lock lock(m_Mutex);
-       m_Calls.push_back(call);
-       m_CallAvailable.notify_all();
+       assert(Application::IsMainThread());
+
+       m_SubscribedFunctions.insert(name);
+
+       ScriptFunction::Ptr sf = boost::make_shared<ScriptFunction>(boost::bind(&ScriptInterpreter::ScriptFunctionThunk, this, _1, _2, name));
+       ScriptFunction::Register(name, sf);
 }
 
-void ScriptInterpreter::RegisterMethod(const String& name)
+void ScriptInterpreter::UnsubscribeFunction(const String& name)
 {
-       // TODO: implement
+       assert(Application::IsMainThread());
+
+       m_SubscribedFunctions.erase(name);
+       ScriptFunction::Unregister(name);
 }
index a207376dd7a95d1605802265b9fd4b24eab76b45..e7f22b208728f89e84179a2641e3af8fe990883f 100644 (file)
@@ -25,8 +25,8 @@ namespace icinga
 
 struct ScriptCall
 {
-       String Method;
-       vector<String> Arguments;
+       String Function;
+       vector<Value> 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<Value>& 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<ScriptCall> m_Calls;
        condition_variable m_CallAvailable;
 
+       set<String> m_SubscribedFunctions; /* Not protected by the mutex. */
+
        boost::thread m_Thread;
 
        void ThreadWorkerProc(void);
+
+       void ScriptFunctionThunk(const ScriptTask::Ptr& task,
+           const vector<Value>& arguments, const String& function);
 };
 
 }
index d56bdff91e5a40e7ff60ece13d67430513f35a83..4c48735ba049e672ae997bb0a9487700ab67c890 100644 (file)
@@ -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<Value>& 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);
 }
index 70d19ef8846a542b4386161be5bef9088c03f6b9..73892c2f130686695efc3cc970787d344ddec2a3 100644 (file)
@@ -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<String, PyObject *> m_Functions;
 
-       virtual void ProcessCall(const ScriptCall& call);
+       virtual void ProcessCall(const String& function, const ScriptTask::Ptr& task,
+           const vector<Value>& arguments);
 };
 
 }