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() + "'");
|
||||
|
||||
if (m_Interpreter)
|
||||
m_Interpreter->Stop();
|
||||
|
||||
ScriptLanguage::Ptr language = ScriptLanguage::GetByName(GetLanguage());
|
||||
m_Interpreter = language->CreateInterpreter(GetSelf());
|
||||
m_Interpreter->Start();
|
||||
}
|
||||
|
|
|
@ -22,18 +22,53 @@
|
|||
using namespace icinga;
|
||||
|
||||
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)
|
||||
{
|
||||
ScriptCall call;
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
|
||||
while (WaitForCall(&call))
|
||||
ProcessCall(call);
|
||||
for (;;) {
|
||||
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)
|
||||
{
|
||||
|
@ -42,19 +77,6 @@ void ScriptInterpreter::EnqueueCall(const ScriptCall& call)
|
|||
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)
|
||||
{
|
||||
// TODO: implement
|
||||
|
|
|
@ -41,19 +41,23 @@ public:
|
|||
typedef shared_ptr<ScriptInterpreter> Ptr;
|
||||
typedef weak_ptr<ScriptInterpreter> WeakPtr;
|
||||
|
||||
~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;
|
||||
|
||||
bool WaitForCall(ScriptCall *call);
|
||||
|
||||
void RegisterMethod(const String& name);
|
||||
|
||||
private:
|
||||
boost::mutex m_Mutex;
|
||||
bool m_Shutdown;
|
||||
deque<ScriptCall> m_Calls;
|
||||
condition_variable m_CallAvailable;
|
||||
|
||||
|
|
Loading…
Reference in New Issue