diff options
-rw-r--r-- | includes/LuaTask.h | 8 | ||||
-rw-r--r-- | src/LuaTask.cc | 22 |
2 files changed, 19 insertions, 11 deletions
diff --git a/includes/LuaTask.h b/includes/LuaTask.h index 1f7a0b5..85ce1f8 100644 --- a/includes/LuaTask.h +++ b/includes/LuaTask.h @@ -3,6 +3,8 @@ #include <c++11-surrogates.h> #include <BLua.h> #include <Task.h> +#include <StacklessTask.h> +#include <Buffer.h> namespace Balau { @@ -19,6 +21,7 @@ class LuaExecCell { void throwError() throw (GeneralException); protected: virtual void run(Lua &) = 0; + virtual bool needsStack() { return false; } void setError() { m_gotError = true; } private: Events::Async m_event; @@ -43,6 +46,7 @@ class LuaExecFile : public LuaExecCell { public: LuaExecFile(IO<Handle> file) : m_file(file) { } private: + virtual bool needsStack() { return !m_file.isA<Buffer>(); } virtual void run(Lua &); IO<Handle> m_file; }; @@ -52,14 +56,14 @@ class LuaTask : public Task { ~LuaTask() { L.weaken(); } virtual const char * getName() const { return "LuaTask"; } private: - LuaTask(Lua && __L, LuaExecCell * cell) : L(Move(__L)), m_cell(cell) { } + LuaTask(Lua && __L, LuaExecCell * cell) : L(Move(__L)), m_cell(cell) { if (!cell->needsStack()) setStackless(); } virtual void Do(); Lua L; LuaExecCell * m_cell; friend class LuaMainTask; }; -class LuaMainTask : public Task { +class LuaMainTask : public StacklessTask { public: LuaMainTask(); ~LuaMainTask(); diff --git a/src/LuaTask.cc b/src/LuaTask.cc index 5075c36..30fdef2 100644 --- a/src/LuaTask.cc +++ b/src/LuaTask.cc @@ -42,18 +42,22 @@ void Balau::LuaMainTask::stop() { } void Balau::LuaMainTask::Do() { + LuaExecCell * cell = NULL; for (;;) { - LuaExecCell * cell; Printer::elog(E_TASK, "LuaMainTask at %p tries to pop an ExecCell", this); - while ((cell = m_queue.pop())) { - Printer::elog(E_TASK, "LuaMainTask at %p popped %p", this, cell); - if (dynamic_cast<LuaTaskStopper *>(cell)) { - Printer::elog(E_TASK, "LuaMainTask at %p is stopping", this); - delete cell; - return; - } - TaskMan::registerTask(new LuaTask(L.thread(), cell), this); + try { + cell = m_queue.pop(); + } + catch (Balau::EAgain & e) { + taskSwitch(); + } + Printer::elog(E_TASK, "LuaMainTask at %p popped %p", this, cell); + if (dynamic_cast<LuaTaskStopper *>(cell)) { + Printer::elog(E_TASK, "LuaMainTask at %p is stopping", this); + delete cell; + return; } + TaskMan::registerTask(new LuaTask(L.thread(), cell), this); } } |