ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/jtreg/util/WeakHashMap/GCDuringIteration.java
(Generate patch)

Comparing jsr166/src/test/jtreg/util/WeakHashMap/GCDuringIteration.java (file contents):
Revision 1.7 by jsr166, Tue Dec 8 00:54:24 2015 UTC vs.
Revision 1.8 by jsr166, Thu Feb 18 04:47:12 2016 UTC

# Line 29 | Line 29
29   * @run main GCDuringIteration
30   * @summary Check that iterators work properly in the presence of
31   *          concurrent finalization and removal of elements.
32 < * @key randomness intermittent
32 > * @key randomness
33   */
34  
35 < import java.util.*;
35 > import static java.util.concurrent.TimeUnit.SECONDS;
36 >
37 > import java.lang.ref.WeakReference;
38 > import java.util.Arrays;
39 > import java.util.Iterator;
40 > import java.util.Map;
41 > import java.util.NoSuchElementException;
42 > import java.util.Random;
43 > import java.util.WeakHashMap;
44   import java.util.concurrent.CountDownLatch;
45 + import java.util.function.BooleanSupplier;
46   import jdk.testlibrary.RandomFactory;
47  
48   public class GCDuringIteration {
40    private static void waitForFinalizersToRun() {
41        for (int i = 0; i < 2; i++)
42            tryWaitForFinalizersToRun();
43    }
49  
50 <    private static void tryWaitForFinalizersToRun() {
51 <        System.gc();
52 <        final CountDownLatch fin = new CountDownLatch(1);
53 <        new Object() { protected void finalize() { fin.countDown(); }};
54 <        System.gc();
55 <        try { fin.await(); }
56 <        catch (InterruptedException ie) { throw new Error(ie); }
50 >    /** No guarantees, but effective in practice. */
51 >    static void forceFullGc() {
52 >        CountDownLatch finalizeDone = new CountDownLatch(1);
53 >        WeakReference<?> ref = new WeakReference<Object>(new Object() {
54 >            protected void finalize() { finalizeDone.countDown(); }});
55 >        try {
56 >            for (int i = 0; i < 10; i++) {
57 >                System.gc();
58 >                if (finalizeDone.await(1L, SECONDS) && ref.get() == null) {
59 >                    System.runFinalization(); // try to pick up stragglers
60 >                    return;
61 >                }
62 >            }
63 >        } catch (InterruptedException unexpected) {
64 >            throw new AssertionError("unexpected InterruptedException");
65 >        }
66 >        throw new AssertionError("failed to do a \"full\" gc");
67 >    }
68 >
69 >    static void gcAwait(BooleanSupplier s) {
70 >        for (int i = 0; i < 10; i++) {
71 >            if (s.getAsBoolean())
72 >                return;
73 >            forceFullGc();
74 >        }
75 >        throw new AssertionError("failed to satisfy condition");
76      }
77  
78      // A class with the traditional pessimal hashCode implementation,
# Line 76 | Line 100 | public class GCDuringIteration {
100              if (rnd.nextBoolean()) check(it.hasNext());
101              equal(it.next().getValue(), i);
102          }
103 <        if (rnd.nextBoolean())
104 <            THROWS(NoSuchElementException.class,
105 <                   new F(){void f(){it.next();}});
103 >        if (rnd.nextBoolean()) {
104 >            try {
105 >                it.next();
106 >                throw new AssertionError("should throw");
107 >            } catch (NoSuchElementException success) {}
108 >        }
109 >
110          if (rnd.nextBoolean())
111              check(! it.hasNext());
112      }
# Line 106 | Line 134 | public class GCDuringIteration {
134              int first = firstValue(map);
135              final Iterator<Map.Entry<Foo,Integer>> it = map.entrySet().iterator();
136              foos[first] = null;
137 <            for (int i = 0; i < 10 && map.size() != first; i++)
110 <                tryWaitForFinalizersToRun();
111 <            equal(map.size(), first);
137 >            gcAwait(() -> map.size() == first);
138              checkIterator(it, first-1);
139              equal(map.size(), first);
140              equal(firstValue(map), first-1);
# Line 119 | Line 145 | public class GCDuringIteration {
145              final Iterator<Map.Entry<Foo,Integer>> it = map.entrySet().iterator();
146              it.next();          // protects first entry
147              System.out.println(map.values());
148 +            int oldSize = map.size();
149              foos[first] = null;
150 <            tryWaitForFinalizersToRun();
151 <            equal(map.size(), first+1);
150 >            forceFullGc();
151 >            equal(map.size(), oldSize);
152              System.out.println(map.values());
153              checkIterator(it, first-1);
154              // first entry no longer protected
155 <            for (int i = 0; i < 10 && map.size() != first; i++)
129 <                tryWaitForFinalizersToRun();
130 <            equal(map.size(), first);
155 >            gcAwait(() -> map.size() == first);
156              equal(firstValue(map), first-1);
157          }
158  
# Line 137 | Line 162 | public class GCDuringIteration {
162              it.next();          // protects first entry
163              System.out.println(map.values());
164              foos[first] = foos[first-1] = null;
165 <            tryWaitForFinalizersToRun();
141 <            equal(map.size(), first);
165 >            gcAwait(() -> map.size() == first);
166              equal(firstValue(map), first);
167              System.out.println(map.values());
168              checkIterator(it, first-2);
169              // first entry no longer protected
170 <            for (int i = 0; i < 10 && map.size() != first-1; i++)
147 <                tryWaitForFinalizersToRun();
148 <            equal(map.size(), first-1);
170 >            gcAwait(() -> map.size() == first-1);
171              equal(firstValue(map), first-2);
172          }
173  
# Line 155 | Line 177 | public class GCDuringIteration {
177              it.next();          // protects first entry
178              it.hasNext();       // protects second entry
179              System.out.println(map.values());
180 +            int oldSize = map.size();
181              foos[first] = foos[first-1] = null;
182 <            tryWaitForFinalizersToRun();
182 >            forceFullGc();
183 >            equal(map.size(), oldSize);
184              equal(firstValue(map), first);
161            equal(map.size(), first+1);
185              System.out.println(map.values());
186              checkIterator(it, first-1);
187              // first entry no longer protected
188 <            for (int i = 0; i < 10 && map.size() != first-1; i++)
166 <                tryWaitForFinalizersToRun();
167 <            equal(map.size(), first-1);
188 >            gcAwait(() -> map.size() == first-1);
189              equal(firstValue(map), first-2);
190          }
191  
# Line 173 | Line 194 | public class GCDuringIteration {
194              final Iterator<Map.Entry<Foo,Integer>> it = map.entrySet().iterator();
195              it.next();          // protects first entry
196              System.out.println(map.values());
197 +            equal(map.size(), first+1);
198              foos[first] = foos[first-1] = null;
199 <            tryWaitForFinalizersToRun();
199 >            gcAwait(() -> map.size() == first);
200              it.remove();
201              equal(firstValue(map), first-2);
202              equal(map.size(), first-1);
203              System.out.println(map.values());
204              checkIterator(it, first-2);
205              // first entry no longer protected
206 <            for (int i = 0; i < 10 && map.size() != first-1; i++)
185 <                tryWaitForFinalizersToRun();
186 <            equal(map.size(), first-1);
206 >            gcAwait(() -> map.size() == first-1);
207              equal(firstValue(map), first-2);
208          }
209  
# Line 194 | Line 214 | public class GCDuringIteration {
214              it.remove();
215              it.hasNext();       // protects second entry
216              System.out.println(map.values());
217 +            equal(map.size(), first);
218              foos[first] = foos[first-1] = null;
219 <            tryWaitForFinalizersToRun();
219 >            forceFullGc();
220              equal(firstValue(map), first-1);
221              equal(map.size(), first);
222              System.out.println(map.values());
223              checkIterator(it, first-1);
224 <            for (int i = 0; i < 10 && map.size() != first-1; i++)
204 <                tryWaitForFinalizersToRun();
205 <            equal(map.size(), first-1);
224 >            gcAwait(() -> map.size() == first-1);
225              equal(firstValue(map), first-2);
226          }
227  
# Line 211 | Line 230 | public class GCDuringIteration {
230              final Iterator<Map.Entry<Foo,Integer>> it = map.entrySet().iterator();
231              it.hasNext();       // protects first entry
232              Arrays.fill(foos, null);
233 <            tryWaitForFinalizersToRun();
215 <            equal(map.size(), 1);
233 >            gcAwait(() -> map.size() == 1);
234              System.out.println(map.values());
235              equal(it.next().getValue(), first);
236              check(! it.hasNext());
237 <            for (int i = 0; i < 10 && map.size() != 0; i++)
220 <                tryWaitForFinalizersToRun();
221 <            equal(map.size(), 0);
237 >            gcAwait(() -> map.size() == 0);
238              check(map.isEmpty());
239          }
240      }
# Line 239 | Line 255 | public class GCDuringIteration {
255          try {test(args);} catch (Throwable t) {unexpected(t);}
256          System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
257          if (failed > 0) throw new AssertionError("Some tests failed");}
242    abstract class F {abstract void f() throws Throwable;}
243    void THROWS(Class<? extends Throwable> k, F... fs) {
244        for (F f : fs)
245            try {f.f(); fail("Expected " + k.getName() + " not thrown");}
246            catch (Throwable t) {
247                if (k.isAssignableFrom(t.getClass())) pass();
248                else unexpected(t);}}
258   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines