*
* @param node the node to remove from the list
*/
public synchronized void removeNode(Simulation.Node node) {
Utils.debugMsg("removeNode()", this);
SimulatorThread st = node.getThread();
timing.removeThread(st);
num_threads--;
Utils.debugMsg("Loesche Node "+node.hashCode()+" mit Thread "+st.hashCode(), this);
if (!threadMap.containsKey(st)) {
System.err.println("Versuch, Objekt aus Liste zu loeschen, das gar nicht enthalten ist");
System.exit(1);
return;
} // if
threadMap.remove(st); // remove SimulatorThread from the local list
simMap.remove(st.getSimulator());
nodeMap.remove(new Integer(node.hashCode()));
// Wenn zwischendurch ein Knoten terminiert, dann eigentlich nur, weil
// sein Programm komplett abgearbeitet wurde. Da immer nur ein Knoten
// gleichzeitig aktiv ist, muss es sich hier um den aktiven Knoten
// gehandelt haben. Um Stillstand zu vermeiden, muss also ein neuer
// Knoten als aktiv gekennzeichnet werden, der dann bei einem erneuten
// Aufruf der fire()-Methode den naechsten Knoten abfragt. Der neu zu
// markierende Knoten wird zufaellig ausgesucht.
// Synchronisation hier, damit unten auf dem Monitor das notifyAll
// aufgerufen werden kann, der neue Knoten muss ja wieder aufwachen.
synchronized(condition) {
if (num_threads > 0) { // are there still other threads?
Iterator threadIterator = threadMap.keySet().iterator();
if (threadIterator.hasNext()) { // activate random thread
SimulatorThread thread = (SimulatorThread)threadIterator.next();
SyncEvent event = (SyncEvent) threadMap.get(thread);
event.activate = true;
thread.getSimulator().insertEvent(event, 0); // fire at once
nodeRemoved = true;
} else {
System.err.println("HashMap leer, obwohl Zaehler != 0");
System.exit(1);
}