Skip to content

Commit

Permalink
reuse last python session if possible
Browse files Browse the repository at this point in the history
  • Loading branch information
peak3d committed Apr 22, 2018
1 parent 121cd5c commit dcd9df9
Show file tree
Hide file tree
Showing 6 changed files with 205 additions and 130 deletions.
30 changes: 28 additions & 2 deletions xbmc/interfaces/generic/LanguageInvokerThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ CLanguageInvokerThread::CLanguageInvokerThread(LanguageInvokerPtr invoker, CScri
CLanguageInvokerThread::~CLanguageInvokerThread()
{
Stop(true);
m_invoker = nullptr;
m_invocationManager=nullptr;
}

InvokerState CLanguageInvokerThread::GetState()
Expand All @@ -41,6 +43,12 @@ InvokerState CLanguageInvokerThread::GetState()
return m_invoker->GetState();
}

void CLanguageInvokerThread::Release()
{
m_bStop = true;
m_condition.notify_one();
}

bool CLanguageInvokerThread::execute(const std::string &script, const std::vector<std::string> &arguments)
{
if (m_invoker == NULL || script.empty())
Expand All @@ -49,7 +57,17 @@ bool CLanguageInvokerThread::execute(const std::string &script, const std::vecto
m_script = script;
m_args = arguments;

Create();
if (CThread::IsRunning())
{
std::unique_lock<std::mutex> lck(m_mutex);
m_restart = true;
m_condition.notify_one();
}
else
Create();

//Todo wait until running

return true;
}

Expand All @@ -61,6 +79,8 @@ bool CLanguageInvokerThread::stop(bool wait)
if (!CThread::IsRunning())
return false;

Release();

bool result = true;
if (m_invoker->GetState() < InvokerStateDone)
{
Expand Down Expand Up @@ -88,7 +108,13 @@ void CLanguageInvokerThread::Process()
if (m_invoker == NULL)
return;

m_invoker->Execute(m_script, m_args);
std::unique_lock<std::mutex> lckdl(m_mutex);
do {
m_restart = false;
m_invoker->Execute(m_script, m_args);

m_condition.wait(lckdl, [this] {return m_bStop || m_restart; });
} while (!m_bStop);
}

void CLanguageInvokerThread::OnExit()
Expand Down
8 changes: 8 additions & 0 deletions xbmc/interfaces/generic/LanguageInvokerThread.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ class CLanguageInvokerThread : public ILanguageInvoker, protected CThread

virtual InvokerState GetState();

const std::string &GetScript() const { return m_script; };
LanguageInvokerPtr GetInvoker() const { return m_invoker; };
virtual void Release();

protected:
bool execute(const std::string &script, const std::vector<std::string> &arguments) override;
bool stop(bool wait) override;
Expand All @@ -49,4 +53,8 @@ class CLanguageInvokerThread : public ILanguageInvoker, protected CThread
CScriptInvocationManager *m_invocationManager;
std::string m_script;
std::vector<std::string> m_args;

std::mutex m_mutex;
std::condition_variable m_condition;
bool m_restart = true;
};
49 changes: 37 additions & 12 deletions xbmc/interfaces/generic/ScriptInvocationManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ void CScriptInvocationManager::Uninitialize()
it->second->Uninitialize();

m_invocationHandlers.clear();
m_lastInvokerThread = nullptr;
}

void CScriptInvocationManager::RegisterLanguageInvocationHandler(ILanguageInvocationHandler *invocationHandler, const std::string &extension)
Expand Down Expand Up @@ -191,12 +192,24 @@ bool CScriptInvocationManager::HasLanguageInvoker(const std::string &script) con
return it != m_invocationHandlers.end() && it->second != NULL;
}

LanguageInvokerPtr CScriptInvocationManager::GetLanguageInvoker(const std::string &script) const
LanguageInvokerPtr CScriptInvocationManager::GetLanguageInvoker(const std::string &script)
{
CSingleLock lock(m_critSection);

if (m_lastInvokerThread)
{
if (m_lastInvokerThread->GetState() == InvokerStateDone && m_lastInvokerThread->GetScript() == script)
{
CLog::Log(LOGDEBUG, "%s - Reusing LanguageInvokerThread %d for script %s", __FUNCTION__, m_lastInvokerThread->GetId(), script.c_str());
return m_lastInvokerThread->GetInvoker();
}
m_lastInvokerThread->Release();
m_lastInvokerThread = nullptr;
}

std::string extension = URIUtils::GetExtension(script);
StringUtils::ToLower(extension);

CSingleLock lock(m_critSection);
std::map<std::string, ILanguageInvocationHandler*>::const_iterator it = m_invocationHandlers.find(extension);
if (it != m_invocationHandlers.end() && it->second != NULL)
return LanguageInvokerPtr(it->second->CreateInvoker());
Expand Down Expand Up @@ -230,23 +243,35 @@ int CScriptInvocationManager::ExecuteAsync(const std::string &script, LanguageIn
return -1;
}

CLanguageInvokerThreadPtr invokerThread = CLanguageInvokerThreadPtr(new CLanguageInvokerThread(languageInvoker, this));
if (invokerThread == NULL)
CSingleLock lock(m_critSection);

if (m_lastInvokerThread && m_lastInvokerThread->GetInvoker() == languageInvoker)
{
if (addon != NULL)
m_lastInvokerThread->SetAddon(addon);

lock.Leave();
m_lastInvokerThread->Execute(script, arguments);

return m_lastInvokerThread->GetId();
}

m_lastInvokerThread = CLanguageInvokerThreadPtr(new CLanguageInvokerThread(languageInvoker, this));
if (m_lastInvokerThread == NULL)
return -1;

if (addon != NULL)
invokerThread->SetAddon(addon);
m_lastInvokerThread->SetAddon(addon);

CSingleLock lock(m_critSection);
invokerThread->SetId(m_nextId++);
m_lastInvokerThread->SetId(m_nextId++);

LanguageInvokerThread thread = { invokerThread, script, false };
m_scripts.insert(std::make_pair(invokerThread->GetId(), thread));
m_scriptPaths.insert(std::make_pair(script, invokerThread->GetId()));
LanguageInvokerThread thread = { m_lastInvokerThread, script, false };
m_scripts.insert(std::make_pair(m_lastInvokerThread->GetId(), thread));
m_scriptPaths.insert(std::make_pair(script, m_lastInvokerThread->GetId()));
lock.Leave();
invokerThread->Execute(script, arguments);
m_lastInvokerThread->Execute(script, arguments);

return invokerThread->GetId();
return m_lastInvokerThread->GetId();
}

int CScriptInvocationManager::ExecuteSync(const std::string &script, const ADDON::AddonPtr &addon /* = ADDON::AddonPtr() */, const std::vector<std::string> &arguments /* = std::vector<std::string>() */, uint32_t timeoutMs /* = 0 */, bool waitShutdown /* = false */)
Expand Down
4 changes: 3 additions & 1 deletion xbmc/interfaces/generic/ScriptInvocationManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class CScriptInvocationManager
void RegisterLanguageInvocationHandler(ILanguageInvocationHandler *invocationHandler, const std::set<std::string> &extensions);
void UnregisterLanguageInvocationHandler(ILanguageInvocationHandler *invocationHandler);
bool HasLanguageInvoker(const std::string &script) const;
LanguageInvokerPtr GetLanguageInvoker(const std::string &script) const;
LanguageInvokerPtr GetLanguageInvoker(const std::string &script);

/*!
* \brief Executes the given script asynchronously in a separate thread.
Expand Down Expand Up @@ -129,6 +129,8 @@ class CScriptInvocationManager

LanguageInvocationHandlerMap m_invocationHandlers;
LanguageInvokerThreadMap m_scripts;
CLanguageInvokerThreadPtr m_lastInvokerThread;

std::map<std::string, int> m_scriptPaths;
int m_nextId;
CCriticalSection m_critSection;
Expand Down
Loading

0 comments on commit dcd9df9

Please sign in to comment.