diff options
author | Pixel <pixel@nobis-crew.org> | 2011-10-14 10:08:26 -0700 |
---|---|---|
committer | Pixel <pixel@nobis-crew.org> | 2011-10-14 10:15:34 -0700 |
commit | ae657c4c8358b66d1ef867b8f90b1eaebaaa71ea (patch) | |
tree | 4fea229168e4d44b4716b423c858797327034a0e /includes | |
parent | 20124b259c408a3ad4427df5176553298907106c (diff) |
Further tweaks to the Task class: now a Task can declare being smart, and say it's okay to get a EAgain exception, if the operation is interruptible.
Diffstat (limited to 'includes')
-rw-r--r-- | includes/Handle.h | 5 | ||||
-rw-r--r-- | includes/Task.h | 24 |
2 files changed, 20 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; }; }; |