From 35f31b94b83b2aadd76792827f7d687969b7bbde Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Fri, 20 Jan 2012 18:56:16 -0800 Subject: j3dcore: ensure the orderedBin array in OrderedGroupRetained is consistently locked Introduce a lock object to lock all access as you cannot use an object to lock itself if that reference is ever written over, as is the case here. You can get surprising nullpointer exceptions and indexOutOfbounds from concurrent thread access when you have multiple active views. Signed-off-by: Harvey Harrison --- .../javax/media/j3d/OrderedGroupRetained.java | 53 ++++++++++------------ 1 file changed, 24 insertions(+), 29 deletions(-) (limited to 'src/classes/share') diff --git a/src/classes/share/javax/media/j3d/OrderedGroupRetained.java b/src/classes/share/javax/media/j3d/OrderedGroupRetained.java index 232477a..eebfd5a 100644 --- a/src/classes/share/javax/media/j3d/OrderedGroupRetained.java +++ b/src/classes/share/javax/media/j3d/OrderedGroupRetained.java @@ -48,11 +48,10 @@ class OrderedGroupRetained extends GroupRetained { // This is a vector of free orderedChildId private ArrayList orderedChildIdFreeList = new ArrayList(); - // One OrderedBin per view - OrderedBin[] orderedBin = new OrderedBin[0]; - - // child id of the newly added child - Integer newChildId; +// used to lock the orderedBin array +private final Object lockObj = new Object(); +// One OrderedBin per view +OrderedBin[] orderedBin = new OrderedBin[0]; // ChildCount used by renderBin to initialize the // orderedCollection in each orderedBin (per view) @@ -228,28 +227,23 @@ class OrderedGroupRetained extends GroupRetained { } } - void setOrderedBin(OrderedBin ob, int index) { - synchronized (orderedBin) { - orderedBin[index] = ob; +void setOrderedBin(OrderedBin ob, int index) { + synchronized (lockObj) { + orderedBin[index] = ob; } - } - +} - // Get the orderedBin for this view index - OrderedBin getOrderedBin(int index) { - OrderedBin ob; - synchronized (orderedBin) { - if (index >= orderedBin.length) { - OrderedBin[] newList = new OrderedBin[index+1]; - for (int i= 0; i < orderedBin.length; i++) { - newList[i] = orderedBin[i]; +// Get the orderedBin for this view index +OrderedBin getOrderedBin(int index) { + synchronized (lockObj) { + if (index >= orderedBin.length) { + OrderedBin[] newList = new OrderedBin[index + 1]; + System.arraycopy(orderedBin, 0, newList, 0, orderedBin.length); + orderedBin = newList; } - newList[index] = null; - orderedBin = newList; - } + return orderedBin[index]; } - return (orderedBin[index]); - } +} void updateChildIdTableInserted(int childId, int orderedId) { int size = 0; @@ -411,14 +405,15 @@ class OrderedGroupRetained extends GroupRetained { void clearDerivedDataStructures() { int i; - //System.err.println("og clearDerivedDataStructures " + this); // Clear the orderedBin and childId table for all views // since this orderedGroup has been clearLived! - for (i = 0; i < orderedBin.length; i++) { - if (orderedBin[i] != null) { - orderedBin[i].source = null; - orderedBin[i] = null; - } + synchronized (lockObj) { + for (i = 0; i < orderedBin.length; i++) { + if (orderedBin[i] == null) + continue; + orderedBin[i].source = null; + orderedBin[i] = null; + } } if (orderedChildIdTable != null) { for (i=0; i