blob: d542b22f56493b208331c07c0c67448a23aa85c2 [file] [log] [blame]
igerasim63c31992015-09-11 16:53:09 +03001/*
2 * Copyright (c) 2015, 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 8072466
27 * @summary Deadlock when initializing MulticastSocket and DatagramSocket
28 * @library /lib/testlibrary
29 * @build jdk.testlibrary.*
30 * @run main/othervm MultiDead
31 */
32
33import java.net.DatagramSocket;
34import java.net.MulticastSocket;
35import java.util.concurrent.atomic.AtomicBoolean;
36import java.util.concurrent.atomic.AtomicReference;
37import java.util.concurrent.CountDownLatch;
igerasim4bffb972015-10-29 22:41:34 +030038import static java.util.concurrent.TimeUnit.MILLISECONDS;
igerasim63c31992015-09-11 16:53:09 +030039import jdk.testlibrary.JDKToolLauncher;
igerasim4bffb972015-10-29 22:41:34 +030040import jdk.testlibrary.Utils;
igerasim63c31992015-09-11 16:53:09 +030041
42public class MultiDead {
43 private static final int THREAD_PAIR_COUNT = 4;
44 private static final int CHILDREN_COUNT = 20;
igerasim4bffb972015-10-29 22:41:34 +030045 // at least 2.5 seconds for a child to complete
46 private static final long CHILD_TIMEOUT = 2500;
47 private static final long TIMEOUT =
48 Utils.adjustTimeout(CHILDREN_COUNT * CHILD_TIMEOUT * 2);
igerasim63c31992015-09-11 16:53:09 +030049
50 public static void main(String[] args) throws Throwable {
51 if (args.length == 0 || args[0].equals("parent")) {
52 parentProcess();
53 }
54
55 if (args.length > 0 && args[0].equals("child")) {
56 childProcess();
57 }
58 }
59
60 private static void parentProcess() throws Throwable {
61 JDKToolLauncher launcher = JDKToolLauncher
62 .createUsingTestJDK("java")
63 .addToolArg("MultiDead")
64 .addToolArg("child");
65 ProcessBuilder pb = new ProcessBuilder(launcher.getCommand());
66
67 AtomicReference<Process> child = new AtomicReference<>();
68 AtomicBoolean stopFlag = new AtomicBoolean(false);
69
70 Thread th = new Thread(() -> {
71 for (int i = 0; i < CHILDREN_COUNT; ++i) {
72 System.out.println("child #" + (i + 1) + " of " +
73 CHILDREN_COUNT);
igerasim4bffb972015-10-29 22:41:34 +030074 long start = System.nanoTime();
igerasim63c31992015-09-11 16:53:09 +030075 try {
76 child.set(pb.start());
77 child.get().waitFor();
78 if (stopFlag.get()) {
79 break;
80 }
81 } catch (Exception e) {
82 throw new RuntimeException(e);
83 }
igerasim4bffb972015-10-29 22:41:34 +030084 if (System.nanoTime() - start >
85 MILLISECONDS.toNanos(CHILD_TIMEOUT)) {
86 System.err.println("Machine is too slow, " +
87 "skipping the test...");
88 break;
89 }
igerasim63c31992015-09-11 16:53:09 +030090 }
91 });
92
93 th.start();
igerasim4bffb972015-10-29 22:41:34 +030094 th.join(TIMEOUT);
95
igerasim63c31992015-09-11 16:53:09 +030096 stopFlag.set(true);
97 if (th.isAlive()) {
98 if (child.get() != null) {
99 child.get().destroyForcibly();
100 }
101 throw new RuntimeException("Failed to complete on time.");
102 }
103 }
104
105 private static void childProcess() {
106 CountDownLatch latch = new CountDownLatch(1);
107 for (int i = 0; i < THREAD_PAIR_COUNT; ++i) {
108 new Thread(() -> {
109 try {
110 latch.await();
111 try (MulticastSocket a = new MulticastSocket(6000)) {
112 }
113 } catch (Exception ignore) {
114 }
115 }).start();
116
117 new Thread(() -> {
118 try {
119 latch.await();
120 try (DatagramSocket b = new DatagramSocket(6000)) {
121 }
122 } catch (Exception ignore) {
123 }
124 }).start();
125 }
126 latch.countDown();
127 }
128}