From f3855293ca369025119a323430d46385f9b04db0 Mon Sep 17 00:00:00 2001 From: hsc Date: Tue, 3 Apr 2012 14:05:24 +0000 Subject: [PATCH] bugfix: properly remove remaining events of terminating experiment Before this commit, EventList::getEventsOf() broke when *two* experiment flows terminated in direct succession: (*it)->getParent() fails if the underlying event doesn't exist anymore. To fix this, I moved the event removal from SimulatorController to EventList::remove(flow), and made it work on the internal event list magic similarly to EventList::remove(event). And I tested it with a few known-working experiments. git-svn-id: https://www4.informatik.uni-erlangen.de/i4svn/danceos/trunk/devel/fail@1022 8c4709b5-6ec9-48aa-a5cd-a96041d1645a --- core/SAL/SimulatorController.cc | 11 +--------- core/SAL/SimulatorController.hpp | 12 +++-------- core/controller/EventList.cc | 34 ++++++++++++++++++++++++------ core/controller/EventList.hpp | 11 +++------- core/controller/ExperimentFlow.hpp | 2 +- 5 files changed, 35 insertions(+), 35 deletions(-) diff --git a/core/SAL/SimulatorController.cc b/core/SAL/SimulatorController.cc index fbdc973c..04d031e0 100644 --- a/core/SAL/SimulatorController.cc +++ b/core/SAL/SimulatorController.cc @@ -210,15 +210,6 @@ void SimulatorController::onJumpEvent(bool flagTriggered, unsigned opcode) m_EvList.fireActiveEvents(); } -void SimulatorController::cleanup(fi::ExperimentFlow* pExp) -{ - // remove related events: - std::vector evlist; - m_EvList.getEventsOf(pExp, evlist); - for(size_t i = 0; i < evlist.size(); i++) - m_EvList.remove(evlist[i]); -} - void SimulatorController::addFlow(fi::ExperimentFlow* flow) { // Store the (flow,corohandle)-tuple internally and create its coroutine: @@ -230,7 +221,7 @@ void SimulatorController::addFlow(fi::ExperimentFlow* flow) void SimulatorController::removeFlow(fi::ExperimentFlow* flow) { // remove all remaining events of this flow - cleanup(flow); + clearEvents(flow); // remove coroutine m_Flows.remove(flow); } diff --git a/core/SAL/SimulatorController.hpp b/core/SAL/SimulatorController.hpp index a7dd3105..a72b5175 100644 --- a/core/SAL/SimulatorController.hpp +++ b/core/SAL/SimulatorController.hpp @@ -214,10 +214,10 @@ class SimulatorController */ void removeEvent(fi::BaseEvent* ev) { m_EvList.remove(ev); } /** - * Removes all previously added events for all experiments. This is - * equal to removeEvent(NULL); + * Removes all previously added events for all experiments. To + * restrict this to a specific experiment flow, pass a pointer to it. */ - void clearEvents() { removeEvent(NULL); } + void clearEvents(fi::ExperimentFlow *flow = 0) { m_EvList.remove(flow); } /** * Waits on any events which have been added to the event management. If * one of those events occour, waitAny() will return the id of that @@ -233,12 +233,6 @@ class SimulatorController * this pointer will be equal to ev) */ fi::BaseEvent* addEventAndWait(fi::BaseEvent* ev); - /** - * Removes all residual events associated with the specified experiment - * flow \a pExp. - * @param pExp the experiment whose events should be removed - */ - void cleanup(fi::ExperimentFlow* pExp); /** * Fetches data for the experiments from the Job-Server. * @return the Experiment-Data from the Job-Server. diff --git a/core/controller/EventList.cc b/core/controller/EventList.cc index 276c06d9..4b69c018 100644 --- a/core/controller/EventList.cc +++ b/core/controller/EventList.cc @@ -51,14 +51,34 @@ EventList::iterator EventList::m_remove(iterator it, bool skip_deletelist) return (m_BufferList.erase(it)); } -void EventList::getEventsOf(ExperimentFlow* pWhat, - std::vector& dest) const +void EventList::remove(ExperimentFlow* flow) { - assert(pWhat && "FATAL ERROR: The context cannot be NULL!"); - for(bufferlist_t::const_iterator it = m_BufferList.begin(); - it != m_BufferList.end(); it++) - if((*it)->getParent() == pWhat) - dest.push_back(*it); + // all events? + if (flow == 0) { + m_BufferList.clear(); + } else { + for (bufferlist_t::iterator it = m_BufferList.begin(); + it != m_BufferList.end(); ) { + if ((*it)->getParent() == flow) { + it = m_BufferList.erase(it); + } else { + ++it; + } + } + } + // events that just fired / are about to fire ... + for (firelist_t::const_iterator it = m_FireList.begin(); + it != m_FireList.end(); it++) { + if (std::find(m_DeleteList.begin(), m_DeleteList.end(), *it) + != m_DeleteList.end()) { + continue; + } + // ... need to be pushed into m_DeleteList, as we're currently + // iterating over m_FireList in fireActiveEvents() and cannot modify it + if (flow == 0 || (*it)->getParent() == flow) { + m_DeleteList.push_back(*it); + } + } } EventList::~EventList() diff --git a/core/controller/EventList.hpp b/core/controller/EventList.hpp index 4b62bd7c..cc5bc45c 100644 --- a/core/controller/EventList.hpp +++ b/core/controller/EventList.hpp @@ -130,15 +130,10 @@ class EventList */ BaseEvent* getEventFromId(EventId id); /** - * Retrieves all events for the specified experiment. - * @param pWhat pointer to experiment context (this pointer is expected - * to be valid!) - * @param dest a reference to a vector-object to be used as the - * destination buffer for the machting event objects. This - * objects may remains unchanged if no matching event objects - * were found. + * Removes all events for the specified experiment. + * @param flow pointer to experiment context (0 = all experiments) */ - void getEventsOf(ExperimentFlow* pWhat, std::vector& dest) const; + void remove(ExperimentFlow* flow); /** * Retrieves the number of experiments which currently have active * events. This number is trivially equal to the (current) total diff --git a/core/controller/ExperimentFlow.hpp b/core/controller/ExperimentFlow.hpp index 60a48267..37862c82 100644 --- a/core/controller/ExperimentFlow.hpp +++ b/core/controller/ExperimentFlow.hpp @@ -32,7 +32,7 @@ class ExperimentFlow void coroutine_entry() { run(); - sal::simulator.cleanup(this); // remove residual events + sal::simulator.clearEvents(this); // remove residual events } };