diff options
author | Nicolas "Pixel" Noble <pixel@nobis-crew.org> | 2013-08-05 02:44:56 +0200 |
---|---|---|
committer | Nicolas "Pixel" Noble <pixel@nobis-crew.org> | 2013-08-05 02:44:56 +0200 |
commit | f29524bb7a37db02f5c98854f76e855dbafa6575 (patch) | |
tree | 276689d53ec79cf88f7c9a4aabaa919db823adad | |
parent | c6518eb6e1caa68cdf0dc242d52cfc172b96efdc (diff) |
Relaxing the simple context rules a bit.
-rw-r--r-- | includes/Task.h | 33 | ||||
-rw-r--r-- | src/BLua.cc | 2 | ||||
-rw-r--r-- | src/Task.cc | 1 |
3 files changed, 26 insertions, 10 deletions
diff --git a/includes/Task.h b/includes/Task.h index 3219397..9539d7d 100644 --- a/includes/Task.h +++ b/includes/Task.h @@ -14,12 +14,15 @@ namespace Balau { namespace Events { class BaseEvent; }; +class Task; + class EAgain : public GeneralException { public: - EAgain(Events::BaseEvent * evt) : GeneralException(), m_evt(evt) { } Events::BaseEvent * getEvent() { return m_evt; } private: + EAgain(Events::BaseEvent * evt) : GeneralException(), m_evt(evt) { } Events::BaseEvent * m_evt; + friend class Task; }; class TaskSwitch : public GeneralException { @@ -28,7 +31,6 @@ class TaskSwitch : public GeneralException { }; class TaskMan; -class Task; namespace Events { @@ -176,8 +178,10 @@ class Task { }; protected: void yield() throw (GeneralException) { - if (yield(false)) + if (yield(false)) { + AAssert(!m_cannotEAgain, "task at %p in simple context mode can't EAgain", this); throw EAgain(NULL); + } } virtual void Do() = 0; void waitFor(Events::BaseEvent * event); @@ -199,8 +203,10 @@ class Task { private: void yield(Events::BaseEvent * evt) throw (GeneralException) { waitFor(evt); - if (yield(false)) + if (yield(false)) { + AAssert(!m_cannotEAgain, "task at %p in simple context mode can't EAgain", this); throw EAgain(NULL); + } } bool yield(bool stillRunning); static size_t stackSize() { return 64 * 1024; } @@ -210,13 +216,22 @@ class Task { static void CALLBACK coroutineTrampoline(void *); void coroutine(); bool enterSimpleContext() { - AAssert(!m_stackless, "You can't enter a simple context in a stackless task"); - bool r = m_okayToEAgain; - m_okayToEAgain = false; + bool r; + if (m_stackless) { + r = m_cannotEAgain; + m_cannotEAgain = true; + } else { + r = m_okayToEAgain; + m_okayToEAgain = false; + } return r; } void leaveSimpleContext(bool oldStatus) { - m_okayToEAgain = oldStatus; + if (m_stackless) { + m_cannotEAgain = oldStatus; + } else { + m_okayToEAgain = oldStatus; + } } void * m_stack = NULL; #ifndef _WIN32 @@ -232,7 +247,7 @@ class Task { Lock m_eventLock; typedef std::list<Events::TaskEvent *> waitedByList_t; waitedByList_t m_waitedBy; - bool m_okayToEAgain = false, m_stackless = false; + bool m_okayToEAgain = false, m_stackless = false, m_cannotEAgain = false; Task(const Task &) = delete; Task & operator=(const Task &) = delete; }; diff --git a/src/BLua.cc b/src/BLua.cc index 7eda510..2bc726e 100644 --- a/src/BLua.cc +++ b/src/BLua.cc @@ -870,7 +870,7 @@ bool Balau::Lua::yieldC() throw (GeneralException) { Future<int> * p = (Future<int> *) touserdata(-2); if (p->m_ranOnce) - throw EAgain(p->m_evt); + Task::operationYield(p->m_evt, Task::STACKLESS); resumeC(); return yieldC(); diff --git a/src/Task.cc b/src/Task.cc index ed03532..345d310 100644 --- a/src/Task.cc +++ b/src/Task.cc @@ -301,6 +301,7 @@ void Balau::Task::operationYield(Events::BaseEvent * evt, enum OperationYieldTyp return; if ((yieldType != SIMPLE) && t->m_okayToEAgain && !gotSignal && doEAgain) { + AAssert(!t->m_cannotEAgain, "task at %p in simple context mode can't EAgain", t); Printer::elog(E_TASK, "operation is throwing an EAgain exception with event %p", evt); throw EAgain(evt); } |