diff options
-rw-r--r-- | includes/Task.h | 22 | ||||
-rw-r--r-- | src/Task.cc | 31 | ||||
-rw-r--r-- | tests/test-Tasks.cc | 1 |
3 files changed, 43 insertions, 11 deletions
diff --git a/includes/Task.h b/includes/Task.h index 64156ba..042624d 100644 --- a/includes/Task.h +++ b/includes/Task.h @@ -49,9 +49,10 @@ class BaseEvent { class Timeout : public BaseEvent { public: - Timeout(ev_tstamp tstamp); - void evt_cb(ev::timer & w, int revents); - void set(ev_tstamp tstamp); + Timeout(ev_tstamp tstamp) { set(tstamp); } + virtual ~Timeout() { m_evt.stop(); } + void evt_cb(ev::timer & w, int revents) { doSignal(); } + void set(ev_tstamp tstamp) { m_evt.set<Timeout, &Timeout::evt_cb>(this); m_evt.set(tstamp); } private: virtual void gotOwner(Task * task); ev::timer m_evt; @@ -60,9 +61,24 @@ class Timeout : public BaseEvent { class TaskEvent : public BaseEvent { public: TaskEvent(Task * taskWaited); + virtual ~TaskEvent(); + void ack(); Task * taskWaited() { return m_taskWaited; } private: Task * m_taskWaited; + bool m_ack; +}; + +class Async : public BaseEvent { + public: + Async() { m_evt.set<Async, &Async::evt_cb>(this); } + virtual ~Async() { m_evt.stop(); } + void trigger() { m_evt.send(); } + void evt_cb(ev::async & w, int revents) { doSignal(); } + protected: + virtual void gotOwner(Task * task); + private: + ev::async m_evt; }; class Custom : public BaseEvent { diff --git a/src/Task.cc b/src/Task.cc index 202d6ab..558b7de 100644 --- a/src/Task.cc +++ b/src/Task.cc @@ -91,17 +91,31 @@ void Balau::Events::BaseEvent::doSignal() { } } -Balau::Events::TaskEvent::TaskEvent(Task * taskWaited) : m_taskWaited(taskWaited) { +Balau::Events::TaskEvent::TaskEvent(Task * taskWaited) : m_taskWaited(taskWaited), m_ack(false) { m_taskWaited->m_waitedBy.push_back(this); } -Balau::Events::Timeout::Timeout(ev_tstamp tstamp) { - set(tstamp); +Balau::Events::TaskEvent::~TaskEvent() { + if (!m_ack) + ack(); } -void Balau::Events::Timeout::set(ev_tstamp tstamp) { - m_evt.set<Timeout, &Timeout::evt_cb>(this); - m_evt.set(tstamp); +void Balau::Events::TaskEvent::ack() { + Assert(!m_ack); + bool deleted = false; + Task * t = m_taskWaited; + Task::waitedByList_t::iterator i; + for (i = t->m_waitedBy.begin(); i != t->m_waitedBy.end(); i++) { + if (*i == this) { + t->m_waitedBy.erase(i); + deleted = true; + break; + } + } + Printer::elog(E_TASK, "TaskEvent at %p being ack; removing from the 'waited by' list of %p (%s - %s); deleted = %s", this, t, t->getName(), ClassName(t).c_str(), deleted ? "true" : "false"); + Assert(deleted); + m_ack = true; + reset(); } void Balau::Events::Timeout::gotOwner(Task * task) { @@ -109,8 +123,9 @@ void Balau::Events::Timeout::gotOwner(Task * task) { m_evt.start(); } -void Balau::Events::Timeout::evt_cb(ev::timer & w, int revents) { - doSignal(); +void Balau::Events::Async::gotOwner(Task * task) { + m_evt.set(task->getLoop()); + m_evt.start(); } void Balau::Events::Custom::gotOwner(Task * task) { diff --git a/tests/test-Tasks.cc b/tests/test-Tasks.cc index 9f07dda..2760e52 100644 --- a/tests/test-Tasks.cc +++ b/tests/test-Tasks.cc @@ -38,6 +38,7 @@ void MainTask::Do() { Assert(!taskEvt.gotSignal()); yield(); Assert(taskEvt.gotSignal()); + taskEvt.ack(); Events::Timeout timeout(0.1); waitFor(&timeout); |