From bd35da4e12bae00ded027c290b1c6757334f67de Mon Sep 17 00:00:00 2001 From: Pixel Date: Sun, 11 Dec 2011 23:43:55 -0800 Subject: Added the ability for a task or an operation to yield. Also optimized some bits of the TaskManager. --- src/Task.cc | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'src/Task.cc') diff --git a/src/Task.cc b/src/Task.cc index cc6fa94..8f30cd4 100644 --- a/src/Task.cc +++ b/src/Task.cc @@ -53,8 +53,8 @@ void Balau::Task::coroutineTrampoline(void * arg) { } void Balau::Task::coroutine() { - IAssert(m_status == STARTING, "The Task at %p was badly initialized ? m_status = %i", this, m_status); try { + IAssert(m_status == STARTING, "The Task at %p was badly initialized ? m_status = %i", this, m_status); m_status = RUNNING; Do(); m_status = STOPPED; @@ -99,9 +99,11 @@ void Balau::Task::coroutine() { void Balau::Task::switchTo() { Printer::elog(E_TASK, "Switching to task %p - %s", this, getName()); - IAssert(m_status == IDLE || m_status == STARTING, "The task at %p isn't either idle or starting... ? m_status = %i", this, m_status); + IAssert(m_status == YIELDED || m_status == IDLE || m_status == STARTING, "The task at %p isn't either yielded, idle or starting... ? m_status = %i", this, m_status); void * oldTLS = g_tlsManager->getTLS(); g_tlsManager->setTLS(m_tls); + if (m_status == YIELDED || m_status == IDLE) + m_status = RUNNING; #ifndef _WIN32 coro_transfer(&m_taskMan->m_returnContext, &m_ctx); #else @@ -112,8 +114,10 @@ void Balau::Task::switchTo() { m_status = IDLE; } -void Balau::Task::yield() { +void Balau::Task::yield(bool changeStatus) { Printer::elog(E_TASK, "Task %p - %s yielding", this, getName()); + if (changeStatus) + m_status = YIELDED; #ifndef _WIN32 coro_transfer(&m_ctx, &m_taskMan->m_returnContext); #else @@ -210,12 +214,18 @@ void Balau::Events::Custom::gotOwner(Task * task) { void Balau::Task::yield(Events::BaseEvent * evt, bool interruptible) throw (GeneralException) { Task * t = getCurrentTask(); - t->waitFor(evt); + if (evt) + t->waitFor(evt); + bool gotSignal; do { - t->yield(); + t->yield(evt == NULL); Printer::elog(E_TASK, "operation back from yielding; interruptible = %s; okayToEAgain = %s", interruptible ? "true" : "false", t->m_okayToEAgain ? "true" : "false"); - } while ((!interruptible || !t->m_okayToEAgain) && !evt->gotSignal()); + gotSignal = evt ? evt->gotSignal() : true; + } while ((!interruptible || !t->m_okayToEAgain) && !gotSignal); + + if (!evt) + return; if (interruptible && t->m_okayToEAgain && !evt->gotSignal()) { Printer::elog(E_TASK, "operation is throwing an exception."); -- cgit v1.2.3