From 20124b259c408a3ad4427df5176553298907106c Mon Sep 17 00:00:00 2001 From: Pixel Date: Fri, 14 Oct 2011 08:52:01 -0700 Subject: Tweaking the Task class a bit. -) setPreemptible now returns the previous state -) Events may now not have an owner -) Events may now have a callback (even though it still needs an owner to get into the ev_loop, for these kind of watchers...) TODO: -) think about a way to start a watcher without requireing a Task -) add a few more things in the Tasks unit tests --- includes/Task.h | 14 ++++++++++++-- src/Task.cc | 9 +++++++-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/includes/Task.h b/includes/Task.h index 1fca27e..b106e9c 100644 --- a/includes/Task.h +++ b/includes/Task.h @@ -13,9 +13,18 @@ class Task; namespace Events { +class BaseEvent; + +class Callback { + protected: + virtual void gotEvent(BaseEvent *) = 0; + friend class BaseEvent; +}; + class BaseEvent { public: - BaseEvent() : m_signal(false), m_task(NULL) { } + BaseEvent() : m_cb(NULL), m_signal(false), m_task(NULL) { } + virtual ~BaseEvent() { if (m_cb) delete m_cb; } bool gotSignal() { return m_signal; } void doSignal(); void reset() { Assert(m_task != NULL); m_signal = false; gotOwner(m_task); } @@ -24,6 +33,7 @@ class BaseEvent { protected: virtual void gotOwner(Task * task) { } private: + Callback * m_cb; bool m_signal; Task * m_task; }; @@ -85,7 +95,7 @@ class Task { void yield(bool override = false); virtual void Do() = 0; void waitFor(Events::BaseEvent * event, bool override = false); - void setPreemptible(bool enable); + bool setPreemptible(bool enable); private: size_t stackSize() { return 128 * 1024; } void switchTo(); diff --git a/src/Task.cc b/src/Task.cc index 938b3de..f7645e6 100644 --- a/src/Task.cc +++ b/src/Task.cc @@ -80,13 +80,15 @@ void Balau::Task::waitFor(Balau::Events::BaseEvent * e, bool override) { m_loop = loop; } -void Balau::Task::setPreemptible(bool enable) { +bool Balau::Task::setPreemptible(bool enable) { + bool wasPreemptible = !m_loop; if (!m_loop && !enable) { m_loop = ev_loop_new(EVFLAG_AUTO); } else if (m_loop) { ev_loop_destroy(m_loop); m_loop = NULL; } + return wasPreemptible; } struct ev_loop * Balau::Task::getLoop() { @@ -98,7 +100,10 @@ struct ev_loop * Balau::Task::getLoop() { void Balau::Events::BaseEvent::doSignal() { m_signal = true; - m_task->getTaskMan()->signalTask(m_task); + if (m_cb) + m_cb->gotEvent(this); + if (m_task) + m_task->getTaskMan()->signalTask(m_task); } Balau::Events::TaskEvent::TaskEvent(Task * taskWaited) : m_taskWaited(taskWaited) { -- cgit v1.2.3