From 1f62143e3bb77d31281d1dc681f931e6339d4a3c Mon Sep 17 00:00:00 2001 From: rachytski Date: Wed, 28 Sep 2011 20:28:07 +0300 Subject: [PATCH] added support for canceling current command. --- base/commands_queue.cpp | 26 +++++++++++++++++++++++--- base/commands_queue.hpp | 22 +++++++++++++++++++--- 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/base/commands_queue.cpp b/base/commands_queue.cpp index 8ea78bd00d..76d6bf4dd0 100644 --- a/base/commands_queue.cpp +++ b/base/commands_queue.cpp @@ -61,10 +61,9 @@ namespace core if (m_parent->m_commands.IsCancelled()) break; - cmd.m_fn(m_env); + m_env.m_isCancelled = false; - if (m_env.IsCancelled()) - break; + cmd.m_fn(m_env); m_parent->FinishCommand(); } @@ -89,6 +88,11 @@ namespace core IRoutine::Cancel(); } + void CommandsQueue::Routine::CancelCommand() + { + m_env.Cancel(); + } + CommandsQueue::Executor::Executor() : m_routine(0) {} @@ -98,6 +102,11 @@ namespace core m_thread.Cancel(); } + void CommandsQueue::Executor::CancelCommand() + { + m_routine->CancelCommand(); + } + CommandsQueue::CommandsQueue(size_t executorsCount) : m_executorsCount(executorsCount), m_cmdId(0), m_activeCommands(0) { @@ -119,6 +128,12 @@ namespace core m_executors = 0; } + void CommandsQueue::CancelCommands() + { + for (size_t i = 0; i < m_executorsCount; ++i) + m_executors[i].CancelCommand(); + } + void CommandsQueue::Start() { for (size_t i = 0; i < m_executorsCount; ++i) @@ -166,6 +181,11 @@ namespace core m_cond.Wait(); } + void CommandsQueue::Clear() + { + m_commands.Clear(); + } + int CommandsQueue::ExecutorsCount() const { return m_executorsCount; diff --git a/base/commands_queue.hpp b/base/commands_queue.hpp index 6d6758bae5..7245a20658 100644 --- a/base/commands_queue.hpp +++ b/base/commands_queue.hpp @@ -8,6 +8,8 @@ namespace core { + /// class, that executes task, specified as a functors on the specified number of threads + /// - all tasks are stored in the single ThreadedList class CommandsQueue { private: @@ -19,6 +21,10 @@ namespace core struct Command; /// execution environment for single command + /// - passed into the task functor + /// - task functor should check the IsCancelled() + /// on the reasonable small interval and cancel + /// it's work upon receiving "true". class Environment { private: @@ -35,13 +41,15 @@ namespace core public: - int GetThreadNum() const; //< number of thread, that is executing the command - bool IsCancelled() const; //< command should ping this flag to see, whether it should cancel execution + int GetThreadNum() const; //< number of thread executing the commands + bool IsCancelled() const; //< command should ping this flag to see, + // whether it should cancel execution }; /// single commmand typedef function function_t; + /// chain of commands struct Chain { list m_fns; @@ -64,6 +72,8 @@ namespace core void operator()(Environment const & env); }; + /// single command. + /// - could be chained together, using Chain class struct Command { uint64_t m_id; @@ -72,6 +82,7 @@ namespace core Command() : m_id(static_cast(-1)) {} + template Command(uint64_t id, tt t) : m_id(id), m_fn(t) @@ -80,6 +91,7 @@ namespace core private: + /// single execution routine class Routine : public threads::IRoutine { private: @@ -95,14 +107,17 @@ namespace core void Do(); void Cancel(); + void CancelCommand(); }; + /// class, which excapsulates thread and routine into single class. struct Executor { threads::Thread m_thread; Routine * m_routine; Executor(); void Cancel(); + void CancelCommand(); }; Executor * m_executors; @@ -110,7 +125,6 @@ namespace core ThreadedList m_commands; uint64_t m_cmdId; - list m_initCommands; list m_finCommands; list m_cancelCommands; @@ -142,7 +156,9 @@ namespace core void Start(); void Cancel(); + void CancelCommands(); void Join(); + void Clear(); template void AddCommand(command_tt cmd)