aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/classes/share/javax/media/j3d/MasterControl.java20
-rw-r--r--src/classes/share/javax/media/j3d/View.java35
2 files changed, 42 insertions, 13 deletions
diff --git a/src/classes/share/javax/media/j3d/MasterControl.java b/src/classes/share/javax/media/j3d/MasterControl.java
index 798d308..a3c90dd 100644
--- a/src/classes/share/javax/media/j3d/MasterControl.java
+++ b/src/classes/share/javax/media/j3d/MasterControl.java
@@ -896,7 +896,7 @@ class MasterControl {
}
else {
if (canvasBitCount > 31) {
- throw new InternalError();
+ throw new RuntimeException("Cannot render to more than 32 Canvas3Ds");
}
return (1 << canvasBitCount++);
}
@@ -2948,8 +2948,22 @@ class MasterControl {
} else if (type == PHYSICAL_ENV_CHANGE) {
evaluatePhysicalEnv((View) o);
} else if (type == EMPTY_UNIVERSE) {
- if (views.isEmpty()) {
- destroyUniverseThreads((VirtualUniverse) o);
+ // Issue 81: We need to process this message as long
+ // as there are no views associated with this
+ // universe. Previously, this message was ignored if
+ // there were views associated with *any* universe,
+ // which led to a memory / thread leak.
+ boolean foundView = false;
+ VirtualUniverse univ = (VirtualUniverse) o;
+ View v[] = (View []) views.toArray(false);
+ for (int j = views.size() - 1; j >= 0; j--) {
+ if (v[j].universe == univ) {
+ foundView = true;
+ break;
+ }
+ }
+ if (!foundView) {
+ destroyUniverseThreads(univ);
threadListsChanged = true;
}
} else if (type == START_RENDERER) {
diff --git a/src/classes/share/javax/media/j3d/View.java b/src/classes/share/javax/media/j3d/View.java
index 62bed3d..b4684a7 100644
--- a/src/classes/share/javax/media/j3d/View.java
+++ b/src/classes/share/javax/media/j3d/View.java
@@ -16,6 +16,8 @@ import javax.vecmath.*;
import java.lang.Math;
import java.util.Vector;
import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.Iterator;
import java.util.Enumeration;
import java.awt.*;
import java.awt.event.*;
@@ -2312,6 +2314,8 @@ public class View extends Object {
* @since Java 3D 1.3
*/
public void removeAllCanvas3Ds() {
+ LinkedList tmpCanvases = new LinkedList();
+
synchronized(canvasList) {
int numCanvases = canvases.size();
@@ -2321,23 +2325,34 @@ public class View extends Object {
cv = (Canvas3D) canvases.elementAt(index);
+ // Record list of canvases to be deleted;
+ tmpCanvases.add(cv);
+
canvases.removeElementAt(index);
removeFromCanvasList(cv);
canvasesDirty = true;
+ }
+ }
- // reset canvas will set view to null also
- VirtualUniverse.mc.postRequest(MasterControl.RESET_CANVAS,
- cv);
- cv.pendingView = null;
+ // ISSUE 83: postRequest must *not* be called while holding
+ // canvasList lock. Holding the lock can cause a deadlock.
- if (cv.added) {
- cv.active = false;
- }
- }
+ Iterator iterator = tmpCanvases.iterator();
+ while (iterator.hasNext()) {
+ Canvas3D cv = (Canvas3D)iterator.next();
- computeCanvasesCached();
+ // reset canvas will set view to null also
+ VirtualUniverse.mc.postRequest(MasterControl.RESET_CANVAS,
+ cv);
+ cv.pendingView = null;
+
+ if (cv.added) {
+ cv.active = false;
+ }
}
+ computeCanvasesCached();
+
evaluateActive();
if (universe != null) {
@@ -2387,7 +2402,7 @@ public class View extends Object {
}
}
- // Locks are already acquired before this is called.
+ // Locks are not acquired before this is called.
void computeCanvasesCached() {
synchronized (canvasList) {