summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--includes/LuaTask.h8
-rw-r--r--src/LuaTask.cc22
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);
}
}