1 /*
   2  * Copyright (c) 2016, 2017, 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 /*
  25  * @test
  26  * @bug 8165000 8172547
  27  * @summary Verify no IOException on OS X for large timeout value in select()
  28  * and that timeout does not occur too early on Windows.
  29  * @requires (os.family == "mac" | os.family == "windows")
  30  */
  31 import java.io.IOException;
  32 import java.nio.channels.Selector;
  33 
  34 public class SelectTimeout {
  35     private static final long BIG_TIMEOUT    = 100_000_001_000L; // 8165000
  36     private static final long BIGGER_TIMEOUT = 850_000_000_000_000L; // 8172547
  37     private static final long SLEEP_MILLIS   = 10000;
  38 
  39     private static volatile Exception theException;
  40     private static volatile boolean isTimedOut;
  41 
  42     public static void main(String[] args)
  43         throws IOException, InterruptedException {
  44         int failures = 0;
  45         long[] timeouts =
  46             new long[] {0, BIG_TIMEOUT/2, BIG_TIMEOUT - 1, BIG_TIMEOUT,
  47                 BIGGER_TIMEOUT};
  48         for (long t : timeouts) {
  49             if (!test(t)) {
  50                 failures++;
  51             }
  52         }
  53         if (failures > 0) {
  54             throw new RuntimeException("Test failed!");
  55         } else {
  56             System.out.println("Test succeeded");
  57         }
  58     }
  59 
  60     private static boolean test(final long timeout)
  61         throws InterruptedException, IOException {
  62         theException = null;
  63         isTimedOut = false;
  64 
  65         Selector selector = Selector.open();
  66 
  67         Thread t = new Thread(() -> {
  68             try {
  69                 selector.select(timeout);
  70                 isTimedOut = true;
  71             } catch (IOException ioe) {
  72                 theException = ioe;
  73             }
  74         });
  75         t.start();
  76 
  77         Thread.currentThread().join(SLEEP_MILLIS);
  78         t.interrupt();
  79 
  80         if (theException == null) {
  81             if (timeout > SLEEP_MILLIS && isTimedOut) {
  82                 System.err.printf("Test timed out early with timeout %d%n",
  83                     timeout);
  84                 return false;
  85             } else {
  86                 System.out.printf("Test succeeded with timeout %d%n", timeout);
  87                 return true;
  88             }
  89         } else {
  90             System.err.printf("Test failed with timeout %d%n", timeout);
  91             theException.printStackTrace();
  92             return false;
  93         }
  94     }
  95 }