# HG changeset patch # User bpb # Date 1484324302 28800 # Fri Jan 13 08:18:22 2017 -0800 # Node ID 2244646a326b473fe876de1205672347e3d8b00b # Parent f3115622562a3f63a3641cc1e70983e3af39ffd0 8172547: (se) Selector.select(Long.MAX_VALUE) fires repeatedly Summary: Clamp the jlong-valued select() timeout to INT_MAX for struct timeval Reviewed-by: XXX diff --git a/src/java.base/windows/native/libnio/ch/WindowsSelectorImpl.c b/src/java.base/windows/native/libnio/ch/WindowsSelectorImpl.c --- a/src/java.base/windows/native/libnio/ch/WindowsSelectorImpl.c +++ b/src/java.base/windows/native/libnio/ch/WindowsSelectorImpl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2017, 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 @@ -32,6 +32,7 @@ #define FD_SETSIZE 1024 +#include #include #include @@ -75,8 +76,18 @@ tv = NULL; } else { tv = &timevalue; - tv->tv_sec = (long)(timeout / 1000); - tv->tv_usec = (long)((timeout % 1000) * 1000); + jlong sec = timeout / 1000; + // + // struct timeval members are signed 32-bit integers so the + // signed 64-bit jlong needs to clamped + // + if (sec > INT_MAX) { + tv->tv_sec = INT_MAX; + tv->tv_usec = 0; + } else { + tv->tv_sec = (long)sec; + tv->tv_usec = (long)((timeout % 1000) * 1000); + } } /* Set FD_SET structures required for select */ diff --git a/test/java/nio/channels/Selector/SelectTimeout.java b/test/java/nio/channels/Selector/SelectTimeout.java --- a/test/java/nio/channels/Selector/SelectTimeout.java +++ b/test/java/nio/channels/Selector/SelectTimeout.java @@ -1,46 +1,50 @@ /* -* Copyright (c) 2016, 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. -*/ + * Copyright (c) 2016, 2017, 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 8165000 - * @summary Verify no IOException on OS X for large timeout value in select(). - * @requires (os.family == "mac") + * @bug 8165000 8172547 + * @summary Verify no IOException on OS X for large timeout value in select() + * and that timeout does not occur too early on Windows. + * @requires (os.family == "mac" | os.family == "windows") */ import java.io.IOException; import java.nio.channels.Selector; public class SelectTimeout { - private static final long HUGE_TIMEOUT = 100000001000L; - private static final long SLEEP_MILLIS = 10000; + private static final long BIG_TIMEOUT = 100000001000L; // 8165000 + private static final long BIGGER_TIMEOUT = 850_000_000_000_000L; // 8172547 + private static final long SLEEP_MILLIS = 10000; private static Exception theException; + private static boolean isTimedOut; public static void main(String[] args) throws IOException, InterruptedException { int failures = 0; long[] timeouts = - new long[] {0, HUGE_TIMEOUT/2, HUGE_TIMEOUT - 1, HUGE_TIMEOUT}; + new long[] {0, BIG_TIMEOUT/2, BIG_TIMEOUT - 1, BIG_TIMEOUT, + BIGGER_TIMEOUT}; for (long t : timeouts) { if (!test(t)) { failures++; @@ -56,12 +60,14 @@ private static boolean test(final long timeout) throws InterruptedException, IOException { theException = null; + isTimedOut = false; Selector selector = Selector.open(); Thread t = new Thread(() -> { try { selector.select(timeout); + isTimedOut = true; } catch (IOException ioe) { theException = ioe; } @@ -72,8 +78,14 @@ t.interrupt(); if (theException == null) { - System.out.printf("Test succeeded with timeout %d%n", timeout); - return true; + if (timeout > SLEEP_MILLIS && isTimedOut) { + System.err.printf("Test timed out early with timeout %d%n", + timeout); + return false; + } else { + System.out.printf("Test succeeded with timeout %d%n", timeout); + return true; + } } else { System.err.printf("Test failed with timeout %d%n", timeout); theException.printStackTrace();