From ae657c4c8358b66d1ef867b8f90b1eaebaaa71ea Mon Sep 17 00:00:00 2001 From: Pixel Date: Fri, 14 Oct 2011 10:08:26 -0700 Subject: 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. --- includes/Task.h | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'includes/Task.h') 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 waitedByList_t; waitedByList_t m_waitedBy; struct ev_loop * m_loop; + bool m_okayToEAgain; }; }; -- cgit v1.2.3