blob: f9dc01725d26d1203e19d0d453515fa9dd494cd1 [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;
38import jdk.testlibrary.JDKToolLauncher;
39
40public class MultiDead {
41 private static final int THREAD_PAIR_COUNT = 4;
42 private static final int CHILDREN_COUNT = 20;
43
44 public static void main(String[] args) throws Throwable {
45 if (args.length == 0 || args[0].equals("parent")) {
46 parentProcess();
47 }
48
49 if (args.length > 0 && args[0].equals("child")) {
50 childProcess();
51 }
52 }
53
54 private static void parentProcess() throws Throwable {
55 JDKToolLauncher launcher = JDKToolLauncher
56 .createUsingTestJDK("java")
57 .addToolArg("MultiDead")
58 .addToolArg("child");
59 ProcessBuilder pb = new ProcessBuilder(launcher.getCommand());
60
61 AtomicReference<Process> child = new AtomicReference<>();
62 AtomicBoolean stopFlag = new AtomicBoolean(false);
63
64 Thread th = new Thread(() -> {
65 for (int i = 0; i < CHILDREN_COUNT; ++i) {
66 System.out.println("child #" + (i + 1) + " of " +
67 CHILDREN_COUNT);
68 try {
69 child.set(pb.start());
70 child.get().waitFor();
71 if (stopFlag.get()) {
72 break;
73 }
74 } catch (Exception e) {
75 throw new RuntimeException(e);
76 }
77 }
78 });
79
80 th.start();
81 th.join(CHILDREN_COUNT * 1000); // 1 sec for a child to complete
82 stopFlag.set(true);
83 if (th.isAlive()) {
84 if (child.get() != null) {
85 child.get().destroyForcibly();
86 }
87 throw new RuntimeException("Failed to complete on time.");
88 }
89 }
90
91 private static void childProcess() {
92 CountDownLatch latch = new CountDownLatch(1);
93 for (int i = 0; i < THREAD_PAIR_COUNT; ++i) {
94 new Thread(() -> {
95 try {
96 latch.await();
97 try (MulticastSocket a = new MulticastSocket(6000)) {
98 }
99 } catch (Exception ignore) {
100 }
101 }).start();
102
103 new Thread(() -> {
104 try {
105 latch.await();
106 try (DatagramSocket b = new DatagramSocket(6000)) {
107 }
108 } catch (Exception ignore) {
109 }
110 }).start();
111 }
112 latch.countDown();
113 }
114}