diff options
-rw-r--r-- | includes/Handle.h | 5 | ||||
-rw-r--r-- | includes/Task.h | 24 | ||||
-rw-r--r-- | src/Task.cc | 1 |
3 files changed, 21 insertions, 9 deletions
diff --git a/includes/Handle.h b/includes/Handle.h index 8275199..3339699 100644 --- a/includes/Handle.h +++ b/includes/Handle.h @@ -4,11 +4,6 @@ namespace Balau { -class EAgain : public GeneralException { - public: - EAgain() : GeneralException("Try Again") { } -}; - class ENoEnt : public GeneralException { public: ENoEnt(const char * name) : GeneralException(String("No such file or directory: `") + name + "'") { } diff --git a/includes/Task.h b/includes/Task.h index b106e9c..3d99d26 100644 --- a/includes/Task.h +++ b/includes/Task.h @@ -8,13 +8,21 @@ namespace Balau { +namespace Events { class BaseEvent; }; + +class EAgain : public GeneralException { + public: + EAgain(Events::BaseEvent * evt) : GeneralException("Try Again"), m_evt(evt) { } + Events::BaseEvent * getEvent() { return m_evt; } + private: + Events::BaseEvent * m_evt; +}; + class TaskMan; class Task; namespace Events { -class BaseEvent; - class Callback { protected: virtual void gotEvent(BaseEvent *) = 0; @@ -81,13 +89,15 @@ class Task { virtual const char * getName() = 0; Status getStatus() { return m_status; } static Task * getCurrentTask(); - static void yield(Events::BaseEvent * evt, bool interruptible = false) { + static void yield(Events::BaseEvent * evt, bool interruptible = false) throw (GeneralException) { Task * t = getCurrentTask(); t->waitFor(evt, true); do { t->yield(true); - } while (!interruptible && !evt->gotSignal()); + } while ((!interruptible || !t->m_okayToEAgain) && !evt->gotSignal()); + if (interruptible && t->m_okayToEAgain && !evt->gotSignal()) + throw EAgain(evt); } TaskMan * getTaskMan() { return m_taskMan; } struct ev_loop * getLoop(); @@ -96,6 +106,11 @@ class Task { virtual void Do() = 0; void waitFor(Events::BaseEvent * event, bool override = false); bool setPreemptible(bool enable); + bool setOkayToEAgain(bool enable) { + bool oldValue = m_okayToEAgain; + m_okayToEAgain = enable; + return oldValue; + } private: size_t stackSize() { return 128 * 1024; } void switchTo(); @@ -110,6 +125,7 @@ class Task { typedef std::vector<Events::TaskEvent *> waitedByList_t; waitedByList_t m_waitedBy; struct ev_loop * m_loop; + bool m_okayToEAgain; }; }; diff --git a/src/Task.cc b/src/Task.cc index f7645e6..d31f4e0 100644 --- a/src/Task.cc +++ b/src/Task.cc @@ -22,6 +22,7 @@ Balau::Task::Task() { m_status = STARTING; m_loop = NULL; + m_okayToEAgain = false; } Balau::Task::~Task() { |