IO-535: Thread bug in FileAlterationMonitor#stop(int) (closes #58, #36) Interrupt the thread created by FileAlterationMonitor on stop()
Project: http://git-wip-us.apache.org/repos/asf/commons-io/repo Commit: http://git-wip-us.apache.org/repos/asf/commons-io/commit/a4705cc3 Tree: http://git-wip-us.apache.org/repos/asf/commons-io/tree/a4705cc3 Diff: http://git-wip-us.apache.org/repos/asf/commons-io/diff/a4705cc3 Branch: refs/heads/master Commit: a4705cc3c310ffb422336b319891f63eef021f1c Parents: e9eb2d8 Author: Svetlin Zarev <svetlin.za...@abv.bg> Authored: Sun Apr 29 11:11:00 2018 +0200 Committer: pascalschumacher <pascalschumac...@gmx.net> Committed: Sun Apr 29 11:16:23 2018 +0200 ---------------------------------------------------------------------- .../io/monitor/FileAlterationMonitor.java | 1 + .../monitor/FileAlterationMonitorTestCase.java | 36 ++++++++++++++++++++ 2 files changed, 37 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/commons-io/blob/a4705cc3/src/main/java/org/apache/commons/io/monitor/FileAlterationMonitor.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/io/monitor/FileAlterationMonitor.java b/src/main/java/org/apache/commons/io/monitor/FileAlterationMonitor.java index 3ef82df..5129f23 100644 --- a/src/main/java/org/apache/commons/io/monitor/FileAlterationMonitor.java +++ b/src/main/java/org/apache/commons/io/monitor/FileAlterationMonitor.java @@ -164,6 +164,7 @@ public final class FileAlterationMonitor implements Runnable { } running = false; try { + thread.interrupt(); thread.join(stopInterval); } catch (final InterruptedException e) { Thread.currentThread().interrupt(); http://git-wip-us.apache.org/repos/asf/commons-io/blob/a4705cc3/src/test/java/org/apache/commons/io/monitor/FileAlterationMonitorTestCase.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/io/monitor/FileAlterationMonitorTestCase.java b/src/test/java/org/apache/commons/io/monitor/FileAlterationMonitorTestCase.java index 200f858..1d1037b 100644 --- a/src/test/java/org/apache/commons/io/monitor/FileAlterationMonitorTestCase.java +++ b/src/test/java/org/apache/commons/io/monitor/FileAlterationMonitorTestCase.java @@ -22,9 +22,11 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.File; +import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; import org.apache.commons.io.testtools.TestUtils; import org.junit.Test; @@ -176,4 +178,38 @@ public class FileAlterationMonitorTestCase extends AbstractMonitorTestCase { } fail(label + " " + file + " not found"); } + + /** + * Test case for IO-535 + * + * Verify that {@link FileAlterationMonitor#stop()} stops the created thread + */ + @Test + public void testStopWhileWaitingForNextInterval() throws Exception { + final Collection<Thread> createdThreads = new ArrayList<>(1); + final ThreadFactory threadFactory = new ThreadFactory() { + private final ThreadFactory delegate = Executors.defaultThreadFactory(); + + @Override + public Thread newThread(Runnable r) { + final Thread thread = delegate.newThread(r); + thread.setDaemon(true); //do not leak threads if the test fails + createdThreads.add(thread); + return thread; + } + }; + + final FileAlterationMonitor monitor = new FileAlterationMonitor(1_000); + monitor.setThreadFactory(threadFactory); + + monitor.start(); + assertFalse(createdThreads.isEmpty()); + + Thread.sleep(10); // wait until the watcher thread enters Thread.sleep() + monitor.stop(100); + + for (Thread thread : createdThreads) { + assertFalse("The FileAlterationMonitor did not stop the threads it created.", thread.isAlive()); + } + } }