You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by sc...@apache.org on 2005/05/22 21:23:05 UTC

svn commit: r171360 - in /jakarta/commons/proper/collections/trunk: RELEASE-NOTES.html src/java/org/apache/commons/collections/FastArrayList.java src/test/org/apache/commons/collections/TestFastArrayList.java

Author: scolebourne
Date: Sun May 22 12:23:04 2005
New Revision: 171360

URL: http://svn.apache.org/viewcvs?rev=171360&view=rev
Log:
Simplify code in iterator remove to avoid incorrect ConcurrentModificationException
bug 34690, from Guilhem Lavaux at Kaffe

Modified:
    jakarta/commons/proper/collections/trunk/RELEASE-NOTES.html
    jakarta/commons/proper/collections/trunk/src/java/org/apache/commons/collections/FastArrayList.java
    jakarta/commons/proper/collections/trunk/src/test/org/apache/commons/collections/TestFastArrayList.java

Modified: jakarta/commons/proper/collections/trunk/RELEASE-NOTES.html
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/collections/trunk/RELEASE-NOTES.html?rev=171360&r1=171359&r2=171360&view=diff
==============================================================================
--- jakarta/commons/proper/collections/trunk/RELEASE-NOTES.html (original)
+++ jakarta/commons/proper/collections/trunk/RELEASE-NOTES.html Sun May 22 12:23:04 2005
@@ -61,6 +61,7 @@
 <center><h3>BUG FIXES</h3></center>
 <ul>
 <li>FastArrayList - Fix iterators and views to work better in multithreaded environments</li>
+<li>FastArrayList - Fix iterator remove where ConcurrentModificationException not as expected [34690]</li>
 <li>BoundedFifoBuffer/CircularFifoBuffer - Fix serialization to work in case where buffer serialized when full [31433]</li>
 <li>BoundedFifoBuffer - Fix iterator remove bug causing ArrayIndexOutOfBounds error [33071]</li>
 <li>MultiHashMap.remove(key, item) - Was returning the item even when nothing was removed [32366]</li>

Modified: jakarta/commons/proper/collections/trunk/src/java/org/apache/commons/collections/FastArrayList.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/collections/trunk/src/java/org/apache/commons/collections/FastArrayList.java?rev=171360&r1=171359&r2=171360&view=diff
==============================================================================
--- jakarta/commons/proper/collections/trunk/src/java/org/apache/commons/collections/FastArrayList.java (original)
+++ jakarta/commons/proper/collections/trunk/src/java/org/apache/commons/collections/FastArrayList.java Sun May 22 12:23:04 2005
@@ -1,5 +1,5 @@
 /*
- *  Copyright 2001-2004 The Apache Software Foundation
+ *  Copyright 2001-2005 The Apache Software Foundation
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -1305,7 +1305,7 @@
             }
             get().remove(lastReturnedIndex);
             expected = list;
-            iter = get().listIterator(previousIndex());
+            iter = get().listIterator(lastReturnedIndex);
             lastReturnedIndex = -1;
         }
 

Modified: jakarta/commons/proper/collections/trunk/src/test/org/apache/commons/collections/TestFastArrayList.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/collections/trunk/src/test/org/apache/commons/collections/TestFastArrayList.java?rev=171360&r1=171359&r2=171360&view=diff
==============================================================================
--- jakarta/commons/proper/collections/trunk/src/test/org/apache/commons/collections/TestFastArrayList.java (original)
+++ jakarta/commons/proper/collections/trunk/src/test/org/apache/commons/collections/TestFastArrayList.java Sun May 22 12:23:04 2005
@@ -1,5 +1,5 @@
 /*
- *  Copyright 2001-2004 The Apache Software Foundation
+ *  Copyright 2001-2005 The Apache Software Foundation
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -16,7 +16,9 @@
 package org.apache.commons.collections;
 
 import java.util.ArrayList;
+import java.util.ConcurrentModificationException;
 import java.util.List;
+import java.util.ListIterator;
 
 import junit.framework.Test;
 
@@ -50,6 +52,113 @@
         FastArrayList fal = new FastArrayList();
         fal.setFast(false);
         return (fal);
+    }
+
+    public void testConcurrentModification_alwaysFast() {
+        FastArrayList list = new FastArrayList();
+        list.setFast(true);
+        list.add("a");
+        list.add("b");
+        list.add("c");
+        ListIterator iter = list.listIterator();
+        assertEquals("a", iter.next());
+        assertEquals("b", iter.next());
+        iter.remove();  // checking for no ConcurrentModificationException
+        assertEquals("c", iter.next());
+        assertEquals(false, iter.hasNext());
+        assertEquals("c", iter.previous());
+        assertEquals("a", iter.previous());
+        assertEquals(false, iter.hasPrevious());
+    }
+
+    public void testConcurrentModification_alwaysFastModError() {
+        FastArrayList list = new FastArrayList();
+        list.setFast(true);
+        list.add("a");
+        list.add("b");
+        list.add("c");
+        ListIterator iter = list.listIterator();
+        assertEquals("a", iter.next());
+        assertEquals("b", iter.next());
+        list.remove(1);
+        try {
+            iter.remove();
+        } catch (ConcurrentModificationException ex) {
+            // expected
+        }
+        // iterator state now invalid
+    }
+
+    public void testConcurrentModification_delayedFast() {
+        FastArrayList list = new FastArrayList();
+        list.add("a");
+        list.add("b");
+        list.add("c");
+        ListIterator iter = list.listIterator();
+        assertEquals("a", iter.next());
+        assertEquals("b", iter.next());
+        list.setFast(true);
+        iter.remove();  // checking for no ConcurrentModificationException
+        assertEquals("c", iter.next());
+        assertEquals(false, iter.hasNext());
+        assertEquals("c", iter.previous());
+        assertEquals("a", iter.previous());
+        assertEquals(false, iter.hasPrevious());
+    }
+
+    public void testConcurrentModification_delayedFastModError() {
+        FastArrayList list = new FastArrayList();
+        list.add("a");
+        list.add("b");
+        list.add("c");
+        ListIterator iter = list.listIterator();
+        assertEquals("a", iter.next());
+        assertEquals("b", iter.next());
+        list.setFast(true);
+        list.remove(1);
+        try {
+            iter.remove();
+        } catch (ConcurrentModificationException ex) {
+            // expected
+        }
+        // iterator state now invalid
+    }
+
+    public void testConcurrentModification_alwaysFastPrevious() {
+        FastArrayList list = new FastArrayList();
+        list.setFast(true);
+        list.add("a");
+        list.add("b");
+        list.add("c");
+        ListIterator iter = list.listIterator();
+        assertEquals("a", iter.next());
+        assertEquals("b", iter.next());
+        assertEquals("b", iter.previous());
+        iter.remove();  // checking for no ConcurrentModificationException
+        assertEquals("c", iter.next());
+        assertEquals(false, iter.hasNext());
+        assertEquals("c", iter.previous());
+        assertEquals("a", iter.previous());
+        assertEquals(false, iter.hasPrevious());
+    }
+
+    public void testConcurrentModification_alwaysFastModErrorPrevious() {
+        FastArrayList list = new FastArrayList();
+        list.setFast(true);
+        list.add("a");
+        list.add("b");
+        list.add("c");
+        ListIterator iter = list.listIterator();
+        assertEquals("a", iter.next());
+        assertEquals("b", iter.next());
+        assertEquals("b", iter.previous());
+        list.remove(1);
+        try {
+            iter.remove();
+        } catch (ConcurrentModificationException ex) {
+            // expected
+        }
+        // iterator state now invalid
     }
 
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org