mirror of https://github.com/Icinga/icinga2.git
Properly shut down instances of the ScriptInterpreter class.
This commit is contained in:
parent
74b122d430
commit
d4afb4087d
|
@ -57,6 +57,10 @@ void Script::SpawnInterpreter(void)
|
||||||
{
|
{
|
||||||
Logger::Write(LogInformation, "base", "Reloading script '" + GetName() + "'");
|
Logger::Write(LogInformation, "base", "Reloading script '" + GetName() + "'");
|
||||||
|
|
||||||
|
if (m_Interpreter)
|
||||||
|
m_Interpreter->Stop();
|
||||||
|
|
||||||
ScriptLanguage::Ptr language = ScriptLanguage::GetByName(GetLanguage());
|
ScriptLanguage::Ptr language = ScriptLanguage::GetByName(GetLanguage());
|
||||||
m_Interpreter = language->CreateInterpreter(GetSelf());
|
m_Interpreter = language->CreateInterpreter(GetSelf());
|
||||||
|
m_Interpreter->Start();
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,19 +22,54 @@
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
ScriptInterpreter::ScriptInterpreter(const Script::Ptr& script)
|
ScriptInterpreter::ScriptInterpreter(const Script::Ptr& script)
|
||||||
: m_Thread(&ScriptInterpreter::ThreadWorkerProc, this)
|
{ }
|
||||||
|
|
||||||
|
ScriptInterpreter::~ScriptInterpreter(void)
|
||||||
{
|
{
|
||||||
m_Thread.detach();
|
Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::Start(void)
|
||||||
|
{
|
||||||
|
/* We can't start the thread in the constructor because
|
||||||
|
* the worker thread might end up calling one of the virtual
|
||||||
|
* methods before the object is fully constructed. */
|
||||||
|
|
||||||
|
m_Thread = boost::thread(&ScriptInterpreter::ThreadWorkerProc, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::Stop(void)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
boost::mutex::scoped_lock lock(m_Mutex);
|
||||||
|
|
||||||
|
if (m_Shutdown)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_Shutdown = true;
|
||||||
|
m_CallAvailable.notify_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_Thread.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptInterpreter::ThreadWorkerProc(void)
|
void ScriptInterpreter::ThreadWorkerProc(void)
|
||||||
{
|
{
|
||||||
ScriptCall call;
|
boost::mutex::scoped_lock lock(m_Mutex);
|
||||||
|
|
||||||
while (WaitForCall(&call))
|
for (;;) {
|
||||||
ProcessCall(call);
|
while (m_Calls.empty() && !m_Shutdown)
|
||||||
|
m_CallAvailable.wait(lock);
|
||||||
|
|
||||||
|
if (m_Shutdown)
|
||||||
|
break;
|
||||||
|
|
||||||
|
ScriptCall call = m_Calls.front();
|
||||||
|
m_Calls.pop_front();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ScriptInterpreter::EnqueueCall(const ScriptCall& call)
|
void ScriptInterpreter::EnqueueCall(const ScriptCall& call)
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock lock(m_Mutex);
|
boost::mutex::scoped_lock lock(m_Mutex);
|
||||||
|
@ -42,19 +77,6 @@ void ScriptInterpreter::EnqueueCall(const ScriptCall& call)
|
||||||
m_CallAvailable.notify_all();
|
m_CallAvailable.notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ScriptInterpreter::WaitForCall(ScriptCall *call)
|
|
||||||
{
|
|
||||||
boost::mutex::scoped_lock lock(m_Mutex);
|
|
||||||
|
|
||||||
while (m_Calls.empty())
|
|
||||||
m_CallAvailable.wait(lock);
|
|
||||||
|
|
||||||
*call = m_Calls.front();
|
|
||||||
m_Calls.pop_front();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ScriptInterpreter::RegisterMethod(const String& name)
|
void ScriptInterpreter::RegisterMethod(const String& name)
|
||||||
{
|
{
|
||||||
// TODO: implement
|
// TODO: implement
|
||||||
|
|
|
@ -41,19 +41,23 @@ public:
|
||||||
typedef shared_ptr<ScriptInterpreter> Ptr;
|
typedef shared_ptr<ScriptInterpreter> Ptr;
|
||||||
typedef weak_ptr<ScriptInterpreter> WeakPtr;
|
typedef weak_ptr<ScriptInterpreter> WeakPtr;
|
||||||
|
|
||||||
|
~ScriptInterpreter(void);
|
||||||
|
|
||||||
void EnqueueCall(const ScriptCall& call);
|
void EnqueueCall(const ScriptCall& call);
|
||||||
|
|
||||||
|
void Start(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 ScriptCall& call) = 0;
|
||||||
|
|
||||||
bool WaitForCall(ScriptCall *call);
|
|
||||||
|
|
||||||
void RegisterMethod(const String& name);
|
void RegisterMethod(const String& name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
boost::mutex m_Mutex;
|
boost::mutex m_Mutex;
|
||||||
|
bool m_Shutdown;
|
||||||
deque<ScriptCall> m_Calls;
|
deque<ScriptCall> m_Calls;
|
||||||
condition_variable m_CallAvailable;
|
condition_variable m_CallAvailable;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue