jdk/test/java/nio/file/WatchService/LotsOfCancels.java
changeset 26449 df1302c8e4bd
child 39335 8dcd06ba5682
equal deleted inserted replaced
26448:5853628b0e63 26449:df1302c8e4bd
       
     1 /*
       
     2  * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  */
       
    23 
       
    24 /* @test
       
    25  * @bug 8029516
       
    26  * @summary Bash on WatchKey.cancel with a view to causing a crash when
       
    27  *    an outstanding I/O operation on directory completes after the
       
    28  *    directory has been closed
       
    29  */
       
    30 
       
    31 import java.nio.file.ClosedWatchServiceException;
       
    32 import java.nio.file.FileSystems;
       
    33 import java.nio.file.Files;
       
    34 import java.nio.file.Path;
       
    35 import java.nio.file.WatchKey;
       
    36 import java.nio.file.WatchService;
       
    37 import static java.nio.file.StandardWatchEventKinds.*;
       
    38 import java.util.concurrent.ExecutorService;
       
    39 import java.util.concurrent.Executors;
       
    40 import java.util.concurrent.TimeUnit;
       
    41 
       
    42 public class LotsOfCancels {
       
    43 
       
    44     // set to true for any exceptions
       
    45     static volatile boolean failed;
       
    46 
       
    47     public static void main(String[] args) throws Exception {
       
    48 
       
    49         // create a bunch of directories. Create two tasks for each directory,
       
    50         // one to bash on cancel, the other to poll the events
       
    51         ExecutorService pool = Executors.newCachedThreadPool();
       
    52         try {
       
    53             Path top = Files.createTempDirectory("work");
       
    54             top.toFile().deleteOnExit();
       
    55             for (int i=1; i<=16; i++) {
       
    56                 Path dir = Files.createDirectory(top.resolve("dir-" + i));
       
    57                 WatchService watcher = FileSystems.getDefault().newWatchService();
       
    58                 pool.submit(() -> handle(dir, watcher));
       
    59                 pool.submit(() -> poll(watcher));
       
    60             }
       
    61         } finally {
       
    62             pool.shutdown();
       
    63         }
       
    64 
       
    65         // give thread pool lots of time to terminate
       
    66         if (!pool.awaitTermination(5L, TimeUnit.MINUTES))
       
    67             throw new RuntimeException("Thread pool did not terminate");
       
    68 
       
    69         if (failed)
       
    70             throw new RuntimeException("Test failed, see log for details");
       
    71     }
       
    72 
       
    73     /**
       
    74      * Stress the given WatchService, specifically the cancel method, in
       
    75      * the given directory. Closes the WatchService when done.
       
    76      */
       
    77     static void handle(Path dir, WatchService watcher) {
       
    78         try {
       
    79             try {
       
    80                 Path file = dir.resolve("anyfile");
       
    81                 for (int i=0; i<2000; i++) {
       
    82                     WatchKey key = dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE);
       
    83                     Files.createFile(file);
       
    84                     Files.delete(file);
       
    85                     key.cancel();
       
    86                 }
       
    87             } finally {
       
    88                 watcher.close();
       
    89             }
       
    90         } catch (Exception e) {
       
    91             e.printStackTrace();
       
    92             failed = true;
       
    93         }
       
    94     }
       
    95 
       
    96     /**
       
    97      * Polls the given WatchService in a tight loop. This keeps the event
       
    98      * queue drained, it also hogs a CPU core which seems necessary to
       
    99      * tickle the original bug.
       
   100      */
       
   101     static void poll(WatchService watcher) {
       
   102         try {
       
   103             for (;;) {
       
   104                 WatchKey key = watcher.take();
       
   105                 if (key != null) {
       
   106                     key.pollEvents();
       
   107                     key.reset();
       
   108                 }
       
   109             }
       
   110         } catch (ClosedWatchServiceException expected) {
       
   111             // nothing to do
       
   112         } catch (Exception e) {
       
   113             e.printStackTrace();
       
   114             failed = true;
       
   115         }
       
   116     }
       
   117 
       
   118 }
       
   119