avoid double dispose in case of Disposer.register(d, ()->Disposer.dispose(t)) abomination

This commit is contained in:
Alexey Kudravtsev
2018-12-06 18:43:22 +03:00
parent 6d4f9c3e2e
commit 20453a1c42
2 changed files with 12 additions and 1 deletions
@@ -107,6 +107,7 @@ final class ObjectNode<T> {
ObjectTree.executeActionWithRecursiveGuard(this, myTree.getNodesInExecution(), new ObjectTreeAction<ObjectNode<T>>() {
@Override
public void execute(@NotNull ObjectNode<T> each) {
if (myTree.getDisposalInfo(myObject) != null) return; // already disposed. may happen when someone does `register(obj, ()->Disposer.dispose(t));` abomination
try {
action.beforeTreeExecution(myObject);
}
@@ -167,7 +168,7 @@ final class ObjectNode<T> {
}
}
private void removeFromObjectTree() {
void removeFromObjectTree() {
synchronized (myTree.treeLock) {
myTree.putNode(myObject, null);
if (myParent == null) {
@@ -94,6 +94,16 @@ public class DisposerTest extends TestCase {
assertEquals(Arrays.asList(myFolder2, myLeaf1, myFolder1, myRoot), myDisposedObjects);
}
public void testDisposalOrderNestedDispose() {
Disposer.register(myRoot, myFolder2);
//noinspection SSBasedInspection
Disposer.register(myRoot, () -> Disposer.dispose(myFolder2));
Disposer.dispose(myRoot);
assertEquals(Arrays.asList(myFolder2, myRoot), myDisposedObjects);
}
public void testDirectCallOfDisposable() {
SelDisposable selfDisposable = new SelDisposable("selfDisposable");
Disposer.register(myRoot, selfDisposable);