Author: tfmorris
Date: 2008-05-28 12:30:10-0700
New Revision: 14818
Modified:
trunk/src/argouml-core-model-mdr/src/org/argouml/model/mdr/ModelEventPumpMDRImpl.java
Log:
Issue 5110: Make recursive use of flush illegal. Synchronize event counter on a separate mutex.
Modified: trunk/src/argouml-core-model-mdr/src/org/argouml/model/mdr/ModelEventPumpMDRImpl.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-core-model-mdr/src/org/argouml/model/mdr/ModelEventPumpMDRImpl.java?view=diff&rev=14818&p1=trunk/src/argouml-core-model-mdr/src/org/argouml/model/mdr/ModelEventPumpMDRImpl.java&p2=trunk/src/argouml-core-model-mdr/src/org/argouml/model/mdr/ModelEventPumpMDRImpl.java&r1=14817&r2=14818
==============================================================================
--- trunk/src/argouml-core-model-mdr/src/org/argouml/model/mdr/ModelEventPumpMDRImpl.java (original)
+++ trunk/src/argouml-core-model-mdr/src/org/argouml/model/mdr/ModelEventPumpMDRImpl.java 2008-05-28 12:30:10-0700
@@ -90,11 +90,14 @@
private MDRModelImplementation modelImpl;
- private Object lock = new Byte[0];
+ private Object registrationMutex = new Byte[0];
private MDRepository repository;
- private int pendingEvents;
+ private Boolean eventCountMutex = new Boolean(false);
+ private int pendingEvents = 0;
+
+ private Thread eventThread;
/**
* Map of Element/attribute tuples and the listeners they have registered.
@@ -236,6 +239,11 @@
* @see org.netbeans.api.mdr.events.MDRChangeListener#change
*/
public void change(MDRChangeEvent mdrEvent) {
+
+ if (eventThread == null) {
+ eventThread = Thread.currentThread();
+ }
+
// TODO: This should be done after all events are delivered, but leave
// it here for now to avoid last minute synchronization problems
decrementEvents();
@@ -349,8 +357,11 @@
* @param e Event from MDR indicating a planned change.
* @see org.netbeans.api.mdr.events.MDRPreChangeListener#plannedChange
*/
- public synchronized void plannedChange(MDRChangeEvent e) {
- pendingEvents++;
+ public void plannedChange(MDRChangeEvent e) {
+
+ synchronized (eventCountMutex) {
+ pendingEvents++;
+ }
// Prototypical logging code that can be enabled and modified to
// discover who's creating certain types of events
@@ -379,10 +390,13 @@
* Decrement count of outstanding events and wake
* any waiters when it becomes zero.
*/
- private synchronized void decrementEvents() {
- pendingEvents--;
- if (pendingEvents == 0) {
- notifyAll();
+ private void decrementEvents() {
+
+ synchronized (eventCountMutex) {
+ pendingEvents--;
+ if (pendingEvents <= 0) {
+ eventCountMutex.notifyAll();
+ }
}
}
@@ -397,7 +411,7 @@
// registered for multiple relevant matches
Set<PropertyChangeListener> listeners =
new HashSet<PropertyChangeListener>();
- synchronized (lock) {
+ synchronized (registrationMutex) {
listeners.addAll(elements.getMatches(mofId, event
.getPropertyName()));
@@ -467,7 +481,7 @@
+ ", listener:" + listener
+ "]");
}
- synchronized (lock) {
+ synchronized (registrationMutex) {
elements.register(listener, mofId, propertyNames);
}
}
@@ -496,7 +510,7 @@
+ ", listener:" + listener
+ "]");
}
- synchronized (lock) {
+ synchronized (registrationMutex) {
elements.unregister(listener, mofId, propertyNames);
}
}
@@ -522,7 +536,7 @@
}
Collection<String> subtypes = subtypeMap.get(className);
verifyAttributeNames(className, propertyNames);
- synchronized (lock) {
+ synchronized (registrationMutex) {
listenedClasses.register(listener, className, propertyNames);
for (String subtype : subtypes) {
listenedClasses.register(listener, subtype, propertyNames);
@@ -549,7 +563,7 @@
+ ", listener:" + listener + "]");
}
Collection<String> subtypes = subtypeMap.get(className);
- synchronized (lock) {
+ synchronized (registrationMutex) {
listenedClasses.unregister(listener, className, propertyNames);
for (String subtype : subtypes) {
listenedClasses.unregister(listener, subtype,
@@ -586,14 +600,23 @@
/*
* @see org.argouml.model.ModelEventPump#flushModelEvents()
*/
- public synchronized void flushModelEvents() {
- try {
- while (pendingEvents > 0) {
- wait();
+ public void flushModelEvents() {
+ while (true) {
+ synchronized (eventCountMutex) {
+ if (pendingEvents <= 0
+ // Don't wait on ourselves, we'll deadlock!
+ // TODO: We might want to throw an exception here
+ || Thread.currentThread().equals(eventThread)) {
+ return;
+ }
+ try {
+ eventCountMutex.wait();
+ } catch (InterruptedException e) {
+ LOG.error("Interrupted while waiting in flushModelEvents");
+ }
}
- } catch (InterruptedException e) {
- LOG.error("Interrupted while waiting in flushModelEvents");
}
+
}
/**
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.