[archstudio-commits] svn commit: r7077 - /bna4/trunk/edu.uci.isr.bna4/src/edu/uci/isr/bna4/logics/hints/SynchronizeHintsLogic.java

archstudio-commits-owner at uci.edu archstudio-commits-owner at uci.edu
Sat May 3 20:19:02 PDT 2008


Author: shendric
Date: Sat May  3 20:19:02 2008
New Revision: 7077

Log:
Fixed synchronize hints deadlock

Modified:
    bna4/trunk/edu.uci.isr.bna4/src/edu/uci/isr/bna4/logics/hints/Synchroni=
zeHintsLogic.java

Modified: bna4/trunk/edu.uci.isr.bna4/src/edu/uci/isr/bna4/logics/hints/Syn=
chronizeHintsLogic.java
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- bna4/trunk/edu.uci.isr.bna4/src/edu/uci/isr/bna4/logics/hints/Synchroni=
zeHintsLogic.java (original)
+++ bna4/trunk/edu.uci.isr.bna4/src/edu/uci/isr/bna4/logics/hints/Synchroni=
zeHintsLogic.java Sat May  3 20:19:02 2008
@@ -1,7 +1,6 @@
 package edu.uci.isr.bna4.logics.hints;
 =

 import java.util.Collection;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.locks.Lock;
@@ -40,8 +39,8 @@
 import edu.uci.isr.sysutils.Tuple;
 =

 public class SynchronizeHintsLogic
-    extends AbstractThingLogic
-    implements IBNASynchronousModelListener, IBNAModelListener, IHintRepos=
itoryChangeListener, IBNAMouseListener, IThingLogicManagerListener{
+	extends AbstractThingLogic
+	implements IBNASynchronousModelListener, IBNAModelListener, IHintReposito=
ryChangeListener, IBNAMouseListener, IThingLogicManagerListener{
 =

 	private static final boolean DEBUG =3D false;
 =

@@ -70,14 +69,54 @@
 		return o1 =3D=3D null ? o2 =3D=3D null : o1.equals(o2);
 	}
 =

-	private final Object lock =3D new Object();
 	private final IHintRepository hintRepository;
 =

-	final Collection<Tuple> ignoreThingProperties =3D Collections.synchronize=
dCollection(new HashBag<Tuple>());
-	final Map<Tuple, Object[]> pendingChanges =3D new HashMap<Tuple, Object[]=
>();
-	int inBulkChange =3D 0;
-	boolean mouseDown =3D false;
-	int ignoreChanges =3D 0;
+	volatile int holdingChanges =3D 0;
+	boolean holdingMouseDown =3D false;
+	final Map<Tuple, Object[]> heldChanges =3D new HashMap<Tuple, Object[]>();
+
+	private void bumpHoldingEvents(int i){
+		synchronized(heldChanges){
+			holdingChanges +=3D i;
+			if(holdingChanges <=3D 0){
+				holdingChanges =3D 0;
+				for(Map.Entry<Tuple, Object[]> entry: heldChanges.entrySet()){
+					handleThingChanged((IThing)entry.getKey().getElement(0), entry.getKey=
().getElement(1), entry.getValue()[0], entry.getValue()[1]);
+				}
+				heldChanges.clear();
+			}
+		}
+	}
+
+	volatile int ignoringChanges =3D 0;
+	final Collection<Tuple> ignoringThingProperties =3D new HashBag<Tuple>();
+
+	private void bumpIgnoreChanges(int i){
+		synchronized(ignoringThingProperties){
+			ignoringChanges +=3D i;
+			if(ignoringChanges <=3D 0){
+				ignoringChanges =3D 0;
+			}
+		}
+	}
+
+	public void ignoreBNAChanges(final Runnable r){
+		final IBNAModel model =3D getBNAModel();
+		Lock lock =3D model.getLock();
+		lock.lock();
+		try{
+			model.fireStreamNotificationEvent(BEGIN_IGNORING_CHANGES);
+			try{
+				r.run();
+			}
+			finally{
+				model.fireStreamNotificationEvent(END_IGNORING_CHANGES);
+			}
+		}
+		finally{
+			lock.unlock();
+		}
+	}
 =

 	public SynchronizeHintsLogic(IHintRepository hintRepository){
 		this.hintRepository =3D hintRepository;
@@ -243,56 +282,23 @@
 		}
 	}
 =

-	protected void processPendingChanges(){
-		for(Map.Entry<Tuple, Object[]> entry: pendingChanges.entrySet()){
-			handleThingChanged((IThing)entry.getKey().getElement(0), entry.getKey()=
.getElement(1), entry.getValue()[0], entry.getValue()[1]);
-		}
-		pendingChanges.clear();
-	}
-
-	public void ignoreBNAChanges(final Runnable r){
-		final IBNAModel model =3D getBNAModel();
-		Lock lock =3D model.getLock();
-		lock.lock();
-		try{
-			model.fireStreamNotificationEvent(BEGIN_IGNORING_CHANGES);
-			try{
-				r.run();
-			}
-			finally{
-				model.fireStreamNotificationEvent(END_IGNORING_CHANGES);
-			}
-		}
-		finally{
-			lock.unlock();
-		}
-	}
-
 	public void bnaModelChangedSync(BNAModelEvent evt){
 		switch(evt.getEventType()){
 		case STREAM_NOTIFICATION_EVENT:
-			synchronized(lock){
-				if(BEGIN_IGNORING_CHANGES.equals(evt.getStreamNotification())){
-					ignoreChanges++;
-					if(DEBUG){
-						System.out.println(">" + ignoreChanges + evt);
-					}
-				}
-				else if(END_IGNORING_CHANGES.equals(evt.getStreamNotification())){
-					if(--ignoreChanges < 0){
-						ignoreChanges =3D 0;
-					}
-					if(DEBUG){
-						System.out.println("<" + ignoreChanges + evt);
-					}
-				}
+			if(BEGIN_IGNORING_CHANGES.equals(evt.getStreamNotification())){
+				bumpIgnoreChanges(1);
+			}
+			else if(END_IGNORING_CHANGES.equals(evt.getStreamNotification())){
+				bumpIgnoreChanges(-1);
 			}
 			break;
 =

 		case BULK_CHANGE_BEGIN:
-			synchronized(lock){
-				inBulkChange++;
-			}
+			bumpHoldingEvents(1);
+			break;
+
+		case BULK_CHANGE_END:
+			bumpHoldingEvents(-1);
 			break;
 =

 		case THING_ADDED:
@@ -304,21 +310,16 @@
 				System.out.println("BNA Event: " + evt.getThingEvent());
 			}
 =

-			synchronized(lock){
-
-			}
 			IThing thing =3D evt.getTargetThing();
 			ThingEvent thingEvent =3D evt.getThingEvent();
 			Object propertyName =3D thingEvent.getPropertyName();
 =

 			if(!HINT_INFORMATION_PROPERTY_NAME.equals(propertyName)){
-				synchronized(lock){
-					if(ignoreChanges > 0){
-						ignoreThingProperties.add(new Tuple(evt.getTargetThing().getID(), ev=
t.getThingEvent().getPropertyName()));
-					}
-					else if(!thing.hasProperty(HINT_INFORMATION_PROPERTY_NAME)){
-						initializeHints(thing);
-					}
+				if(ignoringChanges > 0){
+					ignoringThingProperties.add(new Tuple(evt.getTargetThing().getID(), e=
vt.getThingEvent().getPropertyName()));
+				}
+				else if(!thing.hasProperty(HINT_INFORMATION_PROPERTY_NAME)){
+					initializeHints(thing);
 				}
 			}
 		}
@@ -327,40 +328,31 @@
 	public void bnaModelChanged(BNAModelEvent evt){
 		switch(evt.getEventType()){
 =

-		case BULK_CHANGE_END:
-			synchronized(lock){
-				if(--inBulkChange <=3D 0){
-					inBulkChange =3D 0;
-					processPendingChanges();
-				}
-			}
-			break;
-
 		case THING_CHANGED:
 			IThing thing =3D evt.getTargetThing();
 			ThingEvent thingEvent =3D evt.getThingEvent();
 			Object propertyName =3D thingEvent.getPropertyName();
 =

-			if(!ignoreThingProperties.isEmpty() && ignoreThingProperties.remove(new=
 Tuple(thing.getID(), propertyName))){
+			if(!ignoringThingProperties.isEmpty() && ignoringThingProperties.remove=
(new Tuple(thing.getID(), propertyName))){
 				if(DEBUG){
-					System.out.println("Ignored value: " + thing.getProperty(HINT_INFORMA=
TION_PROPERTY_NAME) + " " + thing.getID() + " " + propertyName + " (" + ign=
oreThingProperties.size() + ") " + thingEvent);
+					System.out.println("Ignored value: " + thing.getProperty(HINT_INFORMA=
TION_PROPERTY_NAME) + " " + thing.getID() + " " + propertyName + " (" + ign=
oringThingProperties.size() + ") " + thingEvent);
 				}
 				// do nothing
+				break;
 			}
-			else if(inBulkChange > 0){
-				synchronized(lock){
+			synchronized(heldChanges){
+				if(holdingChanges > 0){
 					Tuple key =3D new Tuple(thing, propertyName);
-					Object[] oldNewValue =3D pendingChanges.get(key);
+					Object[] oldNewValue =3D heldChanges.get(key);
 					if(oldNewValue =3D=3D null){
-						pendingChanges.put(key, oldNewValue =3D new Object[2]);
+						heldChanges.put(key, oldNewValue =3D new Object[2]);
 						oldNewValue[0] =3D thingEvent.getOldPropertyValue();
 					}
 					oldNewValue[1] =3D thingEvent.getNewPropertyValue();
+					break;
 				}
 			}
-			else{
-				handleThingChanged(thing, propertyName, thingEvent.getOldPropertyValue=
(), thingEvent.getNewPropertyValue());
-			}
+			handleThingChanged(thing, propertyName, thingEvent.getOldPropertyValue(=
), thingEvent.getNewPropertyValue());
 		}
 	}
 =

@@ -378,23 +370,16 @@
 	}
 =

 	public void mouseDown(IBNAView view, MouseEvent evt, IThing t, int worldX=
, int worldY){
-		synchronized(lock){
-			if(!mouseDown){
-				mouseDown =3D true;
-				inBulkChange++;
-			}
+		if(!holdingMouseDown){
+			holdingMouseDown =3D true;
+			bumpHoldingEvents(1);
 		}
 	}
 =

 	public void mouseUp(IBNAView view, MouseEvent evt, IThing t, int worldX, =
int worldY){
-		synchronized(lock){
-			if(mouseDown){
-				mouseDown =3D false;
-				if(--inBulkChange <=3D 0){
-					inBulkChange =3D 0;
-					processPendingChanges();
-				}
-			}
+		if(holdingMouseDown){
+			holdingMouseDown =3D false;
+			bumpHoldingEvents(-1);
 		}
 	}
 =





More information about the archstudio-commits mailing list