Bugfix: Clusterrecords were potentially being removed from the hash in the middle of an iteration without using the iterator's safe removal method. This resulted in an array-OOB exception.

git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@3953 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Mike Thomas
2006-03-16 18:45:40 +00:00
parent 03d94291db
commit b38081f60a
@@ -167,6 +167,13 @@ public class SpotSceneManager extends SceneManager
Log.info("Pruning departed body from cluster [boid=" + bodyOid + Log.info("Pruning departed body from cluster [boid=" + bodyOid +
", cluster=" + clrec + "]."); ", cluster=" + clrec + "].");
clrec.removeBody(bodyOid); clrec.removeBody(bodyOid);
if (clrec.size() == 0) {
// If we just removed the last body, destroy the cluster,
// need to use the iterator's removal so we don't
// hose ourselves.
clrec.destroy(false);
cliter.remove();
}
} }
} }
} }
@@ -364,6 +371,10 @@ public class SpotSceneManager extends SceneManager
ClusterRecord clrec = getCluster(bodyOid); ClusterRecord clrec = getCluster(bodyOid);
if (clrec != null) { if (clrec != null) {
clrec.removeBody(bodyOid); clrec.removeBody(bodyOid);
// If that was the last person, destroy the cluster
if (clrec.size() == 0) {
clrec.destroy(true);
}
} }
} }
@@ -374,7 +385,7 @@ public class SpotSceneManager extends SceneManager
{ {
ClusteredBodyObject bobj = (ClusteredBodyObject) ClusteredBodyObject bobj = (ClusteredBodyObject)
CrowdServer.omgr.getObject(bodyOid); CrowdServer.omgr.getObject(bodyOid);
return (bobj == null) ? null : return (bobj == null) ? null :
(ClusterRecord)_clusters.get(bobj.getClusterOid()); (ClusterRecord)_clusters.get(bobj.getClusterOid());
} }
@@ -528,10 +539,6 @@ public class SpotSceneManager extends SceneManager
// Log.debug("Removed " + bodyOid + " from "+ this + "."); // Log.debug("Removed " + bodyOid + " from "+ this + ".");
// if we've removed our last body; stick a fork in ourselves
if (size() == 0) {
destroy();
}
} }
public ClusterObject getClusterObject () public ClusterObject getClusterObject ()
@@ -565,7 +572,7 @@ public class SpotSceneManager extends SceneManager
// if we didn't manage to add our creating user when we first // if we didn't manage to add our creating user when we first
// started up, there's no point in our sticking around // started up, there's no point in our sticking around
if (size() == 0) { if (size() == 0) {
destroy(); destroy(true);
} }
} }
@@ -587,12 +594,17 @@ public class SpotSceneManager extends SceneManager
return "[cluster=" + _cluster + ", size=" + size() + "]"; return "[cluster=" + _cluster + ", size=" + size() + "]";
} }
protected void destroy () protected void destroy (boolean doRemoval)
{ {
// Log.debug("Cluster empty, going away " + // Log.debug("Cluster empty, going away " +
// "[cloid=" + _clobj.getOid() + "]."); // "[cloid=" + _clobj.getOid() + "].");
_ssobj.removeFromClusters(_cluster.getKey()); _ssobj.removeFromClusters(_cluster.getKey());
_clusters.remove(_clobj.getOid());
// If we've also been requested to remove ourself from the clusters
// list, do that.
if (doRemoval) {
_clusters.remove(_clobj.getOid());
}
CrowdServer.omgr.destroyObject(_clobj.getOid()); CrowdServer.omgr.destroyObject(_clobj.getOid());
} }