Properly shut down instances of the ScriptInterpreter class.

This commit is contained in:
Gunnar Beutner 2013-02-14 15:39:53 +01:00
parent 74b122d430
commit d4afb4087d
3 changed files with 50 additions and 20 deletions

View File

@ -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();
}

View File

@ -22,19 +22,54 @@
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)
{
boost::mutex::scoped_lock lock(m_Mutex);
@ -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

View File

@ -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;