diff --git a/src/proc/control/command-queue.hpp b/src/proc/control/command-queue.hpp index 29b611bf5..25152b94f 100644 --- a/src/proc/control/command-queue.hpp +++ b/src/proc/control/command-queue.hpp @@ -23,10 +23,11 @@ /** @file command-queue.hpp ** Implementation building block of ProcDispatcher to organise commands. - ** This is the actual implementation of the command queue and additionally - ** supports some management tasks pertaining to the queue as a whole. + ** This is the actual implementation of the command queue to allow for + ** strictly sequential dispatch of commands to work on the session. ** - ** @todo WIP-WIP as of 12/2016 + ** @todo as of 12/2016 this is fully functional, but we may want to add + ** some further management functions like purging of expired commands ** ** @see CommandQueue_test ** @see proc-dispatcher.hpp @@ -43,26 +44,23 @@ #include "proc/control/command.hpp" #include "lib/iter-stack.hpp" -//#include "common/subsys.hpp" -//#include "lib/depend.hpp" +#include "lib/format-string.hpp" #include "lib/util.hpp" -//#include -//#include - - namespace proc { namespace control { -// using lib::Symbol; -// using std::bind; + namespace error = lumiera::error; + + using util::_Fmt; using lib::unConst; /** - * @todo Type-comment + * Implementation of the Session's command queue. + * @see DispatcherLoop */ class CommandQueue : public lib::IterQueue @@ -73,12 +71,25 @@ namespace control { { } + CommandQueue& + feed (Command const& cmd) + { + if (not cmd.canExec()) + throw error::Logic(_Fmt("Reject '%s'. Not suitably prepared for invocation: %s") + % cmd.getID() % cmd + , LUMIERA_ERROR_UNBOUND_ARGUMENTS); + + lib::IterQueue::feed(cmd); + return *this; + } + void clear() { this->stateCore().clear(); } + /* == diagnostics == */ size_t @@ -94,8 +105,6 @@ namespace control { } }; - ////////////////TODO 12/16 currently just fleshing out the API.... - diff --git a/src/proc/control/looper.hpp b/src/proc/control/looper.hpp index 77d85721e..ef85dc345 100644 --- a/src/proc/control/looper.hpp +++ b/src/proc/control/looper.hpp @@ -26,10 +26,16 @@ ** This helper encapsulates the loop control logic to separate it from actual ** implementation of timing and waiting (per pthread condition variables). ** It exposes a combined condition (to be used for waiting) plus any further - ** controls to manage the operation of the actual queue. The actual tasks to - ** be controlled are installed as functors. - ** - ** @todo WIP-WIP as of 12/2016 + ** state predicates necessary to manage the state transitions regarding the + ** ProcDispatcher implementation: + ** - detect working state, based on a closure to detect an non empty CommandQueue + ** - handle the disabling and shutdown of the dispatching task + ** - detect an idle state to allow the DispatcherLoop to go to sleep + ** - detect the need to run the builder after handling a command + ** - manage timeout to run the builder with a slight latency + ** - manage an extended timeout to enforce builder run eventually. + ** - offer a "check point" where all state is balanced, which can be + ** used as a synchronisation point to halt the loop. ** ** @see DispatcherLooper_test ** @see proc-dispatcher.hpp diff --git a/src/proc/control/proc-dispatcher.cpp b/src/proc/control/proc-dispatcher.cpp index 62b1110ac..5cbfb8432 100644 --- a/src/proc/control/proc-dispatcher.cpp +++ b/src/proc/control/proc-dispatcher.cpp @@ -92,12 +92,10 @@ #include "proc/control/session-command-service.hpp" #include "proc/mobject/session.hpp" #include "backend/thread-wrapper.hpp" -#include "lib/format-string.hpp" #include using backend::ThreadJoinable; -using util::_Fmt; using lib::Sync; using lib::RecursiveLock_Waitable; using std::unique_ptr; @@ -181,26 +179,23 @@ namespace control { clear() override { Lock sync(this); - UNIMPLEMENTED ("clear the queue"); + queue_.clear(); //////////////////////////////////////////TODO notify!!!! } void enqueue (Command cmd) override { - if (not cmd.canExec()) - throw error::Logic(_Fmt("Reject '%s'. Not suitably prepared for invocation: %s") - % cmd.getID() % cmd - , LUMIERA_ERROR_UNBOUND_ARGUMENTS); - UNIMPLEMENTED ("enqueue command"); + Lock sync(this); + queue_.feed (cmd); //////////////////////////////////////////TODO notify!!!! } size_t size() const { - TODO ("implement command processing queue"); - return 0; + Lock sync(this); + return queue_.size(); } void @@ -217,7 +212,7 @@ namespace control { awaitStateProcessed() { Lock blockWaiting(this, &DispatcherLoop::stateIsSynched); - //////////////////////////////////////////TODO find out who will notify us!!!! + //////////////////////////////////////////TODO eternal sleep.... find out who will wake us!!!! } private: diff --git a/tests/45controller.tests b/tests/45controller.tests index 7f6c5ccfb..06c24b518 100644 --- a/tests/45controller.tests +++ b/tests/45controller.tests @@ -117,11 +117,11 @@ return: 0 END -PLANNED "Dispatcher loop control logic" DispatcherLooper_test <