summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--includes/BLua.h6
-rw-r--r--includes/Task.h3
-rw-r--r--src/BLua.cc59
-rw-r--r--tests/test-Lua.cc2
4 files changed, 32 insertions, 38 deletions
diff --git a/includes/BLua.h b/includes/BLua.h
index a464a77..ccf7bee 100644
--- a/includes/BLua.h
+++ b/includes/BLua.h
@@ -162,7 +162,7 @@ class Lua {
void dumpvars(IO<Handle> out, const String & prefix, int idx = -1);
Lua thread(bool saveit = true);
int yield(int nresults = 0) { return lua_yield(L, nresults); }
- int yield(Future<int>) throw (GeneralException) __attribute__((noreturn));
+ int yield(Future<int>) throw (GeneralException);
bool yielded() { return lua_status(L) == LUA_YIELD; }
bool resume(int nargs = 0) throw (GeneralException);
void showstack(int level = M_INFO);
@@ -195,8 +195,8 @@ class Lua {
private:
void dumpvars_i(IO<Handle> out, const String & prefix, int idx);
void dumpvars_r(IO<Handle> out, int idx, int depth = 0) throw (GeneralException);
- bool resumeC();
- bool yieldC() throw (GeneralException);
+ bool resumeC(int & nargs);
+ void yieldC() throw (GeneralException);
void processException(GeneralException & e);
lua_State * L;
diff --git a/includes/Task.h b/includes/Task.h
index 940afe3..a8702b4 100644
--- a/includes/Task.h
+++ b/includes/Task.h
@@ -287,7 +287,6 @@ class Future {
friend class Lua;
func_t m_func;
Events::BaseEvent * m_evt = NULL;
- bool m_ranOnce = false;
};
template<class R>
@@ -298,7 +297,6 @@ R Future<R>::get() {
Task::operationYield(m_evt, Task::INTERRUPTIBLE);
m_evt = NULL;
try {
- m_ranOnce = true;
r = m_func();
return r;
}
@@ -316,7 +314,6 @@ void Future<R>::run() {
Task::operationYield(m_evt, Task::INTERRUPTIBLE);
m_evt = NULL;
try {
- m_ranOnce = true;
m_func();
return;
}
diff --git a/src/BLua.cc b/src/BLua.cc
index bed33a0..247a8ab 100644
--- a/src/BLua.cc
+++ b/src/BLua.cc
@@ -98,7 +98,7 @@ int Balau::LuaStatics::dumpvars(lua_State * __L) {
L.dumpvars(h, prefix);
Task * t = new CopyTask(s, h);
Events::TaskEvent * evt = new Events::TaskEvent(t);
- L.yield(Future<int>([evt, s]() mutable {
+ return L.yield(Future<int>([evt, s]() mutable {
for (;;) {
if (evt->gotSignal()) {
evt->ack();
@@ -767,19 +767,15 @@ Balau::Lua Balau::Lua::thread(bool saveit) {
bool Balau::Lua::resume(int nargs) throw (GeneralException) {
int r;
- if (resumeC()) {
- if (yielded()) {
- yieldC();
- return true;
- } else {
- return false;
- }
- }
+ if (resumeC(nargs))
+ yieldC();
r = lua_resume(L, nargs);
- if (r == LUA_YIELD)
- return yieldC();
+ if (r == LUA_YIELD) {
+ yieldC();
+ return true;
+ }
if (r == 0)
return false;
@@ -805,7 +801,7 @@ bool Balau::Lua::resume(int nargs) throw (GeneralException) {
}
}
-bool Balau::Lua::resumeC() {
+bool Balau::Lua::resumeC(int & nargs) {
if (!yielded())
return false;
@@ -829,9 +825,6 @@ bool Balau::Lua::resumeC() {
delete p;
pop();
- int nargs = 0;
- bool yieldedAgain = false;
-
try {
nargs = f.get();
}
@@ -843,50 +836,54 @@ bool Balau::Lua::resumeC() {
p->m_evt = e.getEvent();
push((void *) p);
push((void *) &s_signature);
- yieldedAgain = true;
}
catch (LuaYield & y) {
Future<int> * p = new Future<int>(y.m_f);
push((void *) p);
push((void *) &s_signature);
- yieldedAgain = true;
}
catch (Balau::GeneralException & e) {
processException(e);
}
- if (!yieldedAgain)
- resume(nargs);
+
return true;
}
int Balau::Lua::yield(Future<int> f) throw (GeneralException) {
- throw LuaYield(f);
+ int r = 0;
+ try {
+ r = f.get();
+ }
+ catch (EAgain & e) {
+ LuaYield y(f);
+ y.m_f.m_evt = e.getEvent();
+ throw y;
+ }
+ return r;
}
-bool Balau::Lua::yieldC() throw (GeneralException) {
+void Balau::Lua::yieldC() throw (GeneralException) {
if (!yielded())
- return true;
+ return;
if (gettop() < 2)
- return true;
+ return;
if (!islightuserdata(-1))
- return true;
+ return;
if (!islightuserdata(-2))
- return true;
+ return;
void * s = touserdata();
if (s != &s_signature)
- return true;
+ return;
Future<int> * p = (Future<int> *) touserdata(-2);
- if (p->m_ranOnce)
- Task::operationYield(p->m_evt, Task::STACKLESS);
-
- resumeC();
- return yieldC();
+ IAssert(p->m_evt, "There should always be an event here at that point...");
+ Task::operationYield(p->m_evt, Task::STACKLESS);
+ IAssert(false, "That point shouldn't be reached.");
}
void Balau::Lua::processException(GeneralException & e) {
diff --git a/tests/test-Lua.cc b/tests/test-Lua.cc
index ed6e754..9337d35 100644
--- a/tests/test-Lua.cc
+++ b/tests/test-Lua.cc
@@ -115,7 +115,7 @@ int sLua_ObjectTest::ObjectTest_proceed_static(Lua & L, int n, int caller) throw
break;
case OBJECTTEST_YIELDTEST:
- L.yield(Future<int>([=]() mutable {
+ return L.yield(Future<int>([=]() mutable {
int y = L.tonumber();
L.pop();
L.push((lua_Number) y + 1);