diff options
author | Harvey Harrison <[email protected]> | 2012-01-20 18:56:16 -0800 |
---|---|---|
committer | Harvey Harrison <[email protected]> | 2012-01-24 10:40:25 -0800 |
commit | 35f31b94b83b2aadd76792827f7d687969b7bbde (patch) | |
tree | 40a5df99762c4be01a30e1a4cf0a870c57cac891 /src/classes | |
parent | 62ec83df630ecd77f5725169c59dd260fc37b05f (diff) |
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 <[email protected]>
Diffstat (limited to 'src/classes')
-rw-r--r-- | src/classes/share/javax/media/j3d/OrderedGroupRetained.java | 53 |
1 files changed, 24 insertions, 29 deletions
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<orderedChildIdTable.length; i++) { |