/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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 4460583 4470470 4840199 6419424 6710579 6596323 6824135 6395224 7142919
* @summary Comprehensive test of asynchronous closing and interruption
* @author Mark Reinhold
*/
public class AsyncCloseAndInterrupt {
try {
} catch (InterruptedException x) { }
}
// Wildcard address localized to this machine -- Windoze doesn't allow
// connecting to a server socket that was previously bound to a true
// wildcard, namely new InetSocketAddress((InetAddress)null, 0).
//
// Server socket that blindly accepts all connections
public void run() {
try {
for (;;) {
}
} catch (IOException x) {
x.printStackTrace();
}
}
};
}
// Server socket that refuses all connections
}
// Dead pipe source and sink
if (deadSource != null)
deadSource.close();
}
// Files
throw new RuntimeException("Cannot create disk file");
return;
}
}
if (p.waitFor() != 0)
throw new IOException("Error creating fifo");
}
// Channel factories
static abstract class ChannelFactory {
}
return name;
}
}
= new ChannelFactory("SocketChannel") {
return SocketChannel.open();
}
};
= new ChannelFactory("SocketChannel") {
}
};
= new ChannelFactory("ServerSocketChannel") {
return ssc;
}
};
= new ChannelFactory("DatagramChannel") {
return dc;
}
};
= new ChannelFactory("Pipe.SourceChannel") {
// ## arrange to close sink
}
};
= new ChannelFactory("Pipe.SinkChannel") {
// ## arrange to close source
}
};
= new ChannelFactory("FileChannel") {
}
};
= new ChannelFactory("FileChannel") {
}
};
// I/O operations
static abstract class Op {
}
}
};
static void clearBuffers() {
}
}
}
&& (n == -1)
&& (rbc instanceof SocketChannel)
return;
}
throw new RuntimeException("Read succeeded");
}
};
clearBuffers();
&& (n == -1)
&& (sbc instanceof SocketChannel)
return;
}
throw new RuntimeException("Read succeeded");
}
};
throw new RuntimeException("Read succeeded");
}
};
if (wbc instanceof SocketChannel)
int n = 0;
for (;;) {
n += d;
break;
break;
}
}
};
if (gbc instanceof SocketChannel)
int n = 0;
for (;;) {
clearBuffers();
n += d;
break;
break;
}
}
};
void setup() {
waitPump("connect wait for pumping refuser ...");
}
throw new RuntimeException("Connection succeeded");
throw new RuntimeException("Connection did not block");
}
};
void setup() {
waitPump("finishConnect wait for pumping refuser ...");
}
sc.configureBlocking(false);
throw new RuntimeException("Connection succeeded");
sc.configureBlocking(true);
if (sc.finishConnect())
throw new RuntimeException("Connection succeeded");
throw new RuntimeException("Connection did not block");
}
};
throw new RuntimeException("Accept succeeded");
}
};
// Use only with diskFileChannelFactory
}
};
// Use only with diskFileChannelFactory
}
};
// Test modes
"pre-interrupt", "interrupt", "close",
"shutdown-input", "shutdown-output"
};
private int test;
volatile boolean ready = false;
{
}
@SuppressWarnings("fallthrough")
switch (test) {
case TEST_PREINTR:
case TEST_INTR:
throw new RuntimeException("Wrong exception thrown: " + x);
break;
case TEST_CLOSE:
case TEST_SHUTO:
throw new RuntimeException("Wrong exception thrown: " + x);
break;
case TEST_SHUTI:
break;
// FALL THROUGH
default:
throw new Error(x);
}
if (test == TEST_SHUTO) {
throw new RuntimeException("Output not shutdown");
// Let this case pass -- CBIE applies to other channel
} else {
throw new RuntimeException("Channel still open");
}
}
}
if (test == TEST_PREINTR)
ready = true;
try {
} catch (ClosedByInterruptException x) {
} catch (AsynchronousCloseException x) {
} finally {
}
}
}
private static volatile boolean pumpDone = false;
private static volatile boolean pumpReady = false;
pumpReady = false;
while (!pumpReady){
sleep(200);
}
}
// Create a pump thread dedicated to saturate refuser's connection backlog
// Can't reliably saturate connection backlog on Windows Server editions
// Saturate the refuser's connection backlog so that further connection
// attempts will be blocked
while (!pumpDone) {
sc.configureBlocking(false);
// Assume that the connection backlog is saturated if a
// client cannot connect to the refuser within 50 miliseconds
}
if (connected) {
// Retain so that finalizer doesn't close
pumpReady = false;
} else {
pumpReady = true;
}
}
return refuserClients.size();
}
};
}
// Test
throws Exception
{
initPipes();
t.start();
do {
sleep(50);
} while (!t.ready);
sleep(100);
switch (test) {
case TEST_INTR:
t.interrupt();
break;
case TEST_CLOSE:
break;
case TEST_SHUTI:
} else {
}
break;
case TEST_SHUTO:
} else {
}
break;
default:
break;
}
t.finishAndThrow(500);
}
// Test INTR cases before PREINTER cases since sometimes
// interrupted threads can't load classes
// Bugs, see FileChannelImpl for details
if (op == TRANSFER_FROM) {
return;
}
return;
}
}
throws Exception
{
if (ch instanceof ReadableByteChannel) {
if (ch instanceof SocketChannel)
}
if (ch instanceof ScatteringByteChannel) {
if (ch instanceof SocketChannel)
}
if (ch instanceof DatagramChannel) {
// Return here: We can't effectively test writes since, if they
// block, they do so only for a fleeting moment unless the network
// interface is overloaded.
return;
}
if (ch instanceof WritableByteChannel) {
if (ch instanceof SocketChannel)
}
if (ch instanceof GatheringByteChannel) {
if (ch instanceof SocketChannel)
}
}
initAcceptor();
initRefuser();
initPipes();
initFile();
+ " on Windows");
} else {
}
// Testing positional file reads and writes is impractical: It requires
// access to a large file soft-mounted via NFS, and even then isn't
// completely guaranteed to work.
//
// Testing map is impractical and arguably unnecessary: It's
// unclear under what conditions mmap(2) will actually block.
+ " operations on Windows");
} else {
// Only the following tests need refuser's connection backlog
// to be saturated
new ThreadFactory() {
t.setDaemon(true);
t.setName("Pumper");
return t;
}
});
pumpDone = false;
try {
waitPump("\nWait for initial Pump");
pumpDone = true;
} finally {
}
}
}
}