changeset 8960:8aaee9c91c63

8137121, PR3162: (fc) Infinite loop FileChannel.truncate Reviewed-by: alanb
author igerasim
date Fri, 09 Oct 2015 20:11:18 +0300
parents 82067c87496d
children 2751730ffae1
files src/share/classes/sun/nio/ch/FileChannelImpl.java test/java/nio/channels/FileChannel/LoopingTruncate.java
diffstat 2 files changed, 73 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/sun/nio/ch/FileChannelImpl.java	Thu Oct 27 01:52:59 2016 +0100
+++ b/src/share/classes/sun/nio/ch/FileChannelImpl.java	Fri Oct 09 20:11:18 2015 +0300
@@ -327,6 +327,7 @@
             int rv = -1;
             long p = -1;
             int ti = -1;
+            long rp = -1;
             try {
                 begin();
                 ti = threads.add();
@@ -352,8 +353,8 @@
                 if (p > size)
                     p = size;
                 do {
-                    rv = (int)position0(fd, p);
-                } while ((rv == IOStatus.INTERRUPTED) && isOpen());
+                    rp = position0(fd, p);
+                } while ((rp == IOStatus.INTERRUPTED) && isOpen());
                 return this;
             } finally {
                 threads.remove(ti);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/nio/channels/FileChannel/LoopingTruncate.java	Fri Oct 09 20:11:18 2015 +0300
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8137121
+ * @summary (fc) Infinite loop FileChannel.truncate
+ * @run main/othervm LoopingTruncate
+ */
+
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import static java.nio.file.StandardOpenOption.*;
+
+public class LoopingTruncate {
+
+    // (int)FATEFUL_SIZE == -3 == IOStatus.INTERRUPTED
+    static long FATEFUL_SIZE = 0x1FFFFFFFDL;
+
+    static long TIMEOUT = 10_000; // 10 seconds
+
+    public static void main(String[] args) throws Throwable {
+        final Path path = Files.createTempFile("LoopingTruncate.tmp", null);
+        try {
+            Thread th = new Thread(new Runnable() {
+                    @Override
+                    public void run() {
+                        try (FileChannel fc = FileChannel.open(path, CREATE, WRITE)) {
+                            fc.position(FATEFUL_SIZE + 1L);
+                            fc.write(ByteBuffer.wrap(new byte[] {0}));
+                            fc.truncate(FATEFUL_SIZE);
+                        } catch (Exception e) {
+                            throw new RuntimeException(e);
+                        }
+                    }
+                });
+            th.start();
+            th.join(TIMEOUT);
+
+            if (th.isAlive()) {
+                th.interrupt();
+                throw new RuntimeException("Failed to complete on time");
+            }
+        } finally {
+            Files.deleteIfExists(path);
+        }
+    }
+}