Path: blob/master/test/jdk/java/nio/file/WatchService/LotsOfCloses.java
41153 views
/*1* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/* @test24* @bug 814819225* @summary Invoking close asynchronously can cause register to fail with26* an IOException rather than a ClosedWatchServiceException27* @run main LotsOfCloses28*/2930import java.io.IOException;31import java.io.UncheckedIOException;32import java.nio.file.ClosedWatchServiceException;33import java.nio.file.FileSystems;34import java.nio.file.Files;35import java.nio.file.Path;36import java.nio.file.StandardWatchEventKinds;37import java.nio.file.WatchService;38import java.util.Random;39import java.util.concurrent.Callable;40import java.util.concurrent.ExecutorService;41import java.util.concurrent.Executors;42import java.util.concurrent.Future;4344public class LotsOfCloses {4546private static final Random RAND = new Random();4748public static void main(String[] args) throws Exception {49Path dir = Files.createTempDirectory("tmp");50ExecutorService pool = Executors.newCachedThreadPool();51try {5253// run the test repeatedly54long start = System.currentTimeMillis();55while ((System.currentTimeMillis() - start) < 5000) {56test(dir, pool);57}5859} finally {60pool.shutdown();61}6263}6465/**66* Create a WatchService to watch for changes in the given directory67* and then attempt to close the WatchService and change a registration68* at the same time.69*/70static void test(Path dir, ExecutorService pool) throws Exception {71WatchService watcher = FileSystems.getDefault().newWatchService();7273// initial registration74dir.register(watcher, StandardWatchEventKinds.ENTRY_CREATE);7576// submit tasks to close the WatchService and update the registration77Future<Void> closeResult;78Future<Boolean> registerResult;7980if (RAND.nextBoolean()) {81closeResult = pool.submit(newCloserTask(watcher));82registerResult = pool.submit(newRegisterTask(watcher, dir));83} else {84registerResult = pool.submit(newRegisterTask(watcher, dir));85closeResult = pool.submit(newCloserTask(watcher));86}8788closeResult.get();89registerResult.get();9091}9293/**94* Returns a task that closes the given WatchService.95*/96static Callable<Void> newCloserTask(WatchService watcher) {97return () -> {98try {99watcher.close();100return null;101} catch (IOException ioe) {102throw new UncheckedIOException(ioe);103}104};105}106107/**108* Returns a task that updates the registration of a directory with109* a WatchService.110*/111static Callable<Boolean> newRegisterTask(WatchService watcher, Path dir) {112return () -> {113try {114dir.register(watcher, StandardWatchEventKinds.ENTRY_DELETE);115return true;116} catch (ClosedWatchServiceException e) {117return false;118} catch (IOException ioe) {119throw new UncheckedIOException(ioe);120}121};122}123}124125126