[icinga-checkins] icinga.org: icinga2/master: Implemented rudimentary function call forwarding for ScriptInterpreter objects .

git at icinga.org git at icinga.org
Thu Feb 14 16:47:43 CET 2013


Module: icinga2
Branch: master
Commit: 8f2ce8e703daeced896cab3389a5e8329ecd958d
URL:    https://git.icinga.org/?p=icinga2.git;a=commit;h=8f2ce8e703daeced896cab3389a5e8329ecd958d

Author: Gunnar Beutner <gunnar.beutner at netways.de>
Date:   Thu Feb 14 16:43:58 2013 +0100

Implemented rudimentary function call forwarding for ScriptInterpreter objects.

---

 lib/base/scriptinterpreter.cpp   |   38 ++++++++++++++++++++++++++++++++------
 lib/base/scriptinterpreter.h     |   17 +++++++++++------
 lib/python/pythoninterpreter.cpp |   29 ++++++++++++++++++++++++-----
 lib/python/pythoninterpreter.h   |    7 ++++++-
 4 files changed, 73 insertions(+), 18 deletions(-)

diff --git a/lib/base/scriptinterpreter.cpp b/lib/base/scriptinterpreter.cpp
index 028edbe..6106560 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::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);
 }
diff --git a/lib/base/scriptinterpreter.h b/lib/base/scriptinterpreter.h
index a207376..e7f22b2 100644
--- a/lib/base/scriptinterpreter.h
+++ b/lib/base/scriptinterpreter.h
@@ -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);
 };
 
 }
diff --git a/lib/python/pythoninterpreter.cpp b/lib/python/pythoninterpreter.cpp
index d56bdff..4c48735 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<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);
 }
diff --git a/lib/python/pythoninterpreter.h b/lib/python/pythoninterpreter.h
index 70d19ef..73892c2 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<String, PyObject *> m_Functions;
 
-	virtual void ProcessCall(const ScriptCall& call);
+	virtual void ProcessCall(const String& function, const ScriptTask::Ptr& task,
+	    const vector<Value>& arguments);
 };
 
 }





More information about the icinga-checkins mailing list