summaryrefslogtreecommitdiff
path: root/src/Task.cc
diff options
context:
space:
mode:
authorNicolas Noble <pixel@nobis-crew.org>2013-08-01 16:02:21 -0700
committerNicolas Noble <pixel@nobis-crew.org>2013-08-01 16:02:21 -0700
commit9d614195cff948d69df417add0b08b2fe44d4ec5 (patch)
treef239c653f6f3d2e1406f01f22f0789b5ef29434d /src/Task.cc
parent4423441cc3f5f80b5e0f6d24dfe8b69828f67ab4 (diff)
I'm surprised this worked so far. The yield / EAgain mechanism was pretty much broken when using stackless operations.
Diffstat (limited to 'src/Task.cc')
-rw-r--r--src/Task.cc11
1 files changed, 6 insertions, 5 deletions
diff --git a/src/Task.cc b/src/Task.cc
index 8e479c3..77217a5 100644
--- a/src/Task.cc
+++ b/src/Task.cc
@@ -144,14 +144,14 @@ void Balau::Task::switchTo() {
IAssert(m_status != RUNNING, "Task %s at %p is still running... ?", getName(), this);
}
-void Balau::Task::yield(bool stillRunning) throw (GeneralException) {
+bool Balau::Task::yield(bool stillRunning) {
Printer::elog(E_TASK, "Task %p - %s yielding", this, getName());
if (stillRunning)
m_status = YIELDED;
else
m_status = SLEEPING;
if (m_stackless) {
- throw EAgain(NULL);
+ return true;
} else {
#ifndef _WIN32
coro_transfer(&m_ctx, &m_taskMan->m_returnContext);
@@ -159,6 +159,7 @@ void Balau::Task::yield(bool stillRunning) throw (GeneralException) {
SwitchToFiber(m_taskMan->m_fiber);
#endif
}
+ return false;
}
Balau::Task * Balau::Task::getCurrentTask() {
@@ -280,10 +281,10 @@ void Balau::Task::operationYield(Events::BaseEvent * evt, enum OperationYieldTyp
AAssert(t->m_okayToEAgain, "You can't run a stackless operation from a non-okay-to-eagain task.");
}
- bool gotSignal;
+ bool gotSignal, doEAgain = false;
do {
- t->yield(evt == NULL);
+ doEAgain = t->yield(evt == NULL);
static const char * YieldTypeToString[] = {
"SIMPLE",
"INTERRUPTIBLE",
@@ -296,7 +297,7 @@ void Balau::Task::operationYield(Events::BaseEvent * evt, enum OperationYieldTyp
if (!evt)
return;
- if ((yieldType != SIMPLE) && t->m_okayToEAgain && !gotSignal) {
+ if ((yieldType != SIMPLE) && t->m_okayToEAgain && !gotSignal && doEAgain) {
Printer::elog(E_TASK, "operation is throwing an exception.");
throw EAgain(evt);
}