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 /includes/Task.h | |
parent | c6518eb6e1caa68cdf0dc242d52cfc172b96efdc (diff) |
Relaxing the simple context rules a bit.
Diffstat (limited to 'includes/Task.h')
-rw-r--r-- | includes/Task.h | 33 |
1 files changed, 24 insertions, 9 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; }; |