From 7d3b54f3c23b28c28f0b8dfc9b3e73ef344e772d Mon Sep 17 00:00:00 2001 From: that Date: Fri, 9 Jan 2015 22:52:51 +0100 Subject: gui: fix action threading if background thread is busy When the background thread is already running and we have at least one threaded action in the list, we should not run any non-threaded actions before ignoring the threaded action and following ones - it might cause invalid state variables to be set. Run or ignore the whole list in the background thread instead. Change-Id: Ie634105b80f038893898a21539886bd757eb47ce --- gui/action.cpp | 24 +++++++++++++++--------- gui/objects.hpp | 3 +-- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/gui/action.cpp b/gui/action.cpp index d54ea0a03..750d73b8d 100644 --- a/gui/action.cpp +++ b/gui/action.cpp @@ -98,18 +98,18 @@ ActionThread::~ActionThread() pthread_mutex_destroy(&m_act_lock); } -void ActionThread::threadActions(GUIAction *act, size_t start_index) +void ActionThread::threadActions(GUIAction *act) { pthread_mutex_lock(&m_act_lock); if (m_thread_running) { pthread_mutex_unlock(&m_act_lock); - LOGERR("Another threaded action is already running -- not running actions '%s' and following\n", act->mActions[start_index].mFunction.c_str()); + LOGERR("Another threaded action is already running -- not running %u actions starting with '%s'\n", + act->mActions.size(), act->mActions[0].mFunction.c_str()); } else { m_thread_running = true; pthread_mutex_unlock(&m_act_lock); ThreadData *d = new ThreadData; d->act = act; - d->start_index = start_index; pthread_create(&m_thread, NULL, &ActionThread_work_wrapper, d); } @@ -121,7 +121,7 @@ void ActionThread::run(void *data) GUIAction* act = d->act; std::vector::iterator it; - for (it = act->mActions.begin() + d->start_index; it != act->mActions.end(); ++it) + for (it = act->mActions.begin(); it != act->mActions.end(); ++it) act->doAction(*it); pthread_mutex_lock(&m_act_lock); @@ -380,18 +380,24 @@ int GUIAction::doActions() if (mActions.size() < 1) return -1; + bool needThread = false; std::vector::iterator it; for (it = mActions.begin(); it != mActions.end(); ++it) { if (needsToRunInSeparateThread(*it)) { - // run all remaining actions in a separate thread - action_thread.threadActions(this, it - mActions.begin()); - // ...and we're done here + needThread = true; break; } - - doAction(*it); + } + if (needThread) + { + action_thread.threadActions(this); + } + else + { + for (it = mActions.begin(); it != mActions.end(); ++it) + doAction(*it); } return 0; diff --git a/gui/objects.hpp b/gui/objects.hpp index 44c2b364e..76dbb4625 100644 --- a/gui/objects.hpp +++ b/gui/objects.hpp @@ -362,13 +362,12 @@ public: ActionThread(); ~ActionThread(); - void threadActions(GUIAction *act, size_t start_index); + void threadActions(GUIAction *act); void run(void *data); private: struct ThreadData { GUIAction *act; - size_t start_index; }; pthread_t m_thread; -- cgit v1.2.3