mirror of https://github.com/Icinga/icinga2.git
Implemented rudimentary function call forwarding for ScriptInterpreter objects.
This commit is contained in:
parent
d3928a7e69
commit
8f2ce8e703
|
@ -40,6 +40,8 @@ void ScriptInterpreter::Start(void)
|
||||||
|
|
||||||
void ScriptInterpreter::Stop(void)
|
void ScriptInterpreter::Stop(void)
|
||||||
{
|
{
|
||||||
|
assert(Application::IsMainThread());
|
||||||
|
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock lock(m_Mutex);
|
boost::mutex::scoped_lock lock(m_Mutex);
|
||||||
|
|
||||||
|
@ -50,6 +52,10 @@ void ScriptInterpreter::Stop(void)
|
||||||
m_CallAvailable.notify_all();
|
m_CallAvailable.notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_FOREACH(const String& function, m_SubscribedFunctions) {
|
||||||
|
ScriptFunction::Unregister(function);
|
||||||
|
}
|
||||||
|
|
||||||
m_Thread.join();
|
m_Thread.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,15 +75,35 @@ void ScriptInterpreter::ThreadWorkerProc(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::ScriptFunctionThunk(const ScriptTask::Ptr& task,
|
||||||
void ScriptInterpreter::EnqueueCall(const ScriptCall& call)
|
const vector<Value>& arguments, const String& function)
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock lock(m_Mutex);
|
ScriptCall call;
|
||||||
m_Calls.push_back(call);
|
call.Function = function;
|
||||||
m_CallAvailable.notify_all();
|
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<ScriptFunction>(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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,8 +25,8 @@ namespace icinga
|
||||||
|
|
||||||
struct ScriptCall
|
struct ScriptCall
|
||||||
{
|
{
|
||||||
String Method;
|
String Function;
|
||||||
vector<String> Arguments;
|
vector<Value> Arguments;
|
||||||
ScriptTask::Ptr Task;
|
ScriptTask::Ptr Task;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -43,17 +43,17 @@ public:
|
||||||
|
|
||||||
~ScriptInterpreter(void);
|
~ScriptInterpreter(void);
|
||||||
|
|
||||||
void EnqueueCall(const ScriptCall& call);
|
|
||||||
|
|
||||||
void Start(void);
|
void Start(void);
|
||||||
void Stop(void);
|
void Stop(void);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ScriptInterpreter(const Script::Ptr& script);
|
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:
|
private:
|
||||||
boost::mutex m_Mutex;
|
boost::mutex m_Mutex;
|
||||||
|
@ -61,9 +61,14 @@ private:
|
||||||
deque<ScriptCall> m_Calls;
|
deque<ScriptCall> m_Calls;
|
||||||
condition_variable m_CallAvailable;
|
condition_variable m_CallAvailable;
|
||||||
|
|
||||||
|
set<String> m_SubscribedFunctions; /* Not protected by the mutex. */
|
||||||
|
|
||||||
boost::thread m_Thread;
|
boost::thread m_Thread;
|
||||||
|
|
||||||
void ThreadWorkerProc(void);
|
void ThreadWorkerProc(void);
|
||||||
|
|
||||||
|
void ScriptFunctionThunk(const ScriptTask::Ptr& task,
|
||||||
|
const vector<Value>& arguments, const String& function);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,8 @@
|
||||||
|
|
||||||
using namespace icinga;
|
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)
|
: ScriptInterpreter(script), m_Language(language), m_ThreadState(NULL)
|
||||||
{
|
{
|
||||||
PyEval_AcquireLock();
|
PyEval_AcquireLock();
|
||||||
|
@ -31,9 +32,11 @@ PythonInterpreter::PythonInterpreter(const PythonLanguage::Ptr& language, const
|
||||||
|
|
||||||
(void) PyThreadState_Swap(m_ThreadState);
|
(void) PyThreadState_Swap(m_ThreadState);
|
||||||
PyRun_SimpleString(script->GetCode().CStr());
|
PyRun_SimpleString(script->GetCode().CStr());
|
||||||
(void) PyThreadState_Swap(m_Language->GetMainThreadState());
|
(void) PyThreadState_Swap(NULL);
|
||||||
|
|
||||||
PyEval_ReleaseLock();
|
PyEval_ReleaseLock();
|
||||||
|
|
||||||
|
SubscribeFunction("python::Test");
|
||||||
}
|
}
|
||||||
|
|
||||||
PythonInterpreter::~PythonInterpreter(void)
|
PythonInterpreter::~PythonInterpreter(void)
|
||||||
|
@ -48,11 +51,27 @@ PythonInterpreter::~PythonInterpreter(void)
|
||||||
PyEval_ReleaseLock();
|
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);
|
PyEval_AcquireThread(m_ThreadState);
|
||||||
PyRun_SimpleString("import antigravity");
|
std::cout << "Received call for method '" << function << "'" << std::endl;
|
||||||
PyEval_ReleaseThread(m_ThreadState);
|
PyEval_ReleaseThread(m_ThreadState);
|
||||||
|
|
||||||
call.Task->FinishResult(0);
|
task->FinishResult(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,11 +37,16 @@ public:
|
||||||
PythonInterpreter(const PythonLanguage::Ptr& language, const Script::Ptr& script);
|
PythonInterpreter(const PythonLanguage::Ptr& language, const Script::Ptr& script);
|
||||||
~PythonInterpreter(void);
|
~PythonInterpreter(void);
|
||||||
|
|
||||||
|
void RegisterFunction(const String& name, PyObject *function);
|
||||||
|
void UnregisterFunction(const String& name);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
PythonLanguage::Ptr m_Language;
|
PythonLanguage::Ptr m_Language;
|
||||||
PyThreadState *m_ThreadState;
|
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);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue