You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by te...@apache.org on 2009/06/16 11:20:10 UTC
svn commit: r785120 - in /harmony/enhanced/classlib/trunk/modules/luni/src:
main/java/java/util/ArrayList.java
test/api/common/org/apache/harmony/luni/tests/java/util/ArrayListTest.java
Author: tellison
Date: Tue Jun 16 09:20:09 2009
New Revision: 785120
URL: http://svn.apache.org/viewvc?rev=785120&view=rev
Log:
Apply patch HARMONY-6236 ([classlib][luni] ArrayList breaks when given concurrent collections as input)
Modified:
harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/util/ArrayList.java
harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/util/ArrayListTest.java
Modified: harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/util/ArrayList.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/util/ArrayList.java?rev=785120&r1=785119&r2=785120&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/util/ArrayList.java (original)
+++ harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/util/ArrayList.java Tue Jun 16 09:20:09 2009
@@ -73,10 +73,11 @@
* the collection of elements to add.
*/
public ArrayList(Collection<? extends E> collection) {
- int size = collection.size();
firstIndex = 0;
+ Object[] objects = collection.toArray();
+ int size = objects.length;
array = newElementArray(size + (size / 10));
- collection.toArray(array);
+ System.arraycopy(objects, 0, array, 0, size);
lastIndex = size;
modCount = 1;
}
@@ -173,7 +174,12 @@
if (this == collection) {
collection = (ArrayList)clone();
}
- int growSize = collection.size();
+ Object[] dumparray = collection.toArray();
+ int growSize = dumparray.length;
+ if (growSize == 0) {
+ return false;
+ }
+
if (0 < location && location < size) {
if (array.length - size < growSize) {
growForInsert(location, growSize);
@@ -205,15 +211,10 @@
lastIndex += growSize;
}
- if (growSize > 0) {
- Object[] dumparray = new Object[growSize];
- collection.toArray(dumparray);
- System.arraycopy(dumparray, 0, this.array, location + firstIndex,
- growSize);
- modCount++;
- return true;
- }
- return false;
+ System.arraycopy(dumparray, 0, this.array, location + firstIndex,
+ growSize);
+ modCount++;
+ return true;
}
/**
Modified: harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/util/ArrayListTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/util/ArrayListTest.java?rev=785120&r1=785119&r2=785120&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/util/ArrayListTest.java (original)
+++ harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/util/ArrayListTest.java Tue Jun 16 09:20:09 2009
@@ -86,6 +86,12 @@
}
+ public void testConstructorWithConcurrentCollection() {
+ Collection<String> collection = shrinksOnSize("A", "B", "C", "D");
+ ArrayList<String> list = new ArrayList<String>(collection);
+ assertFalse(list.contains(null));
+ }
+
/**
* @tests java.util.ArrayList#add(int, java.lang.Object)
*/
@@ -866,6 +872,20 @@
assertEquals(14, list.size());
}
+ public void testAddAllWithConcurrentCollection() {
+ ArrayList<String> list = new ArrayList<String>();
+ list.addAll(shrinksOnSize("A", "B", "C", "D"));
+ assertFalse(list.contains(null));
+ }
+
+ public void testAddAllAtPositionWithConcurrentCollection() {
+ ArrayList<String> list = new ArrayList<String>(
+ Arrays.asList("A", "B", "C", "D"));
+
+ list.addAll(3, shrinksOnSize("E", "F", "G", "H"));
+ assertFalse(list.contains(null));
+ }
+
public void test_override_size() throws Exception {
ArrayList testlist = new MockArrayList();
// though size is overriden, it should passed without exception
@@ -927,4 +947,31 @@
for (int i = 0; i < objArray.length; i++)
alist.add(objArray[i]);
}
+
+ /**
+ * Returns a collection that emulates another thread calling remove() each
+ * time the current thread calls size().
+ */
+ private <T> Collection<T> shrinksOnSize(T... elements) {
+ return new HashSet<T>(Arrays.asList(elements)) {
+ boolean shrink = true;
+
+ @Override
+ public int size() {
+ int result = super.size();
+ if (shrink) {
+ Iterator<T> i = iterator();
+ i.next();
+ i.remove();
+ }
+ return result;
+ }
+
+ @Override
+ public Object[] toArray() {
+ shrink = false;
+ return super.toArray();
+ }
+ };
+ }
}