|
Description
|
java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0)
Java HotSpot(TM) Client VM (build 1.3.0, mixed mode)
ServerSocket.accept does not notice thread interrupts or closes of the
socket:
The code:
import java.net.*;
import java.io.*;
import java.util.*;
public class CloseTest extends Thread
{
ServerSocket socket;
public void run()
{
long start = System.currentTimeMillis();
try
{
socket = new ServerSocket(8080);
socket.setSoTimeout(20000);
System.err.println("Socket="+socket+" accepting...");
socket.accept();
}
catch(Exception e) {e.printStackTrace();}
finally
{
if (System.currentTimeMillis()-start > 19000 )
System.err.println("TOOK TOO LONG TO NOTICE THE INTERRUPT AND/OR
CLOSE!!!");
}
}
public static void main(String[] arg)
{
try
{
CloseTest ct=new CloseTest();
ct.start();
Thread.sleep(1000);
ct.interrupt();
ct.socket.close();
}
catch(Exception e) {e.printStackTrace();}
}
}
produces the following output:
Socket=ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=8080] accepting...
java.net.SocketException: Socket closed
at java.net.PlainSocketImpl.socketAccept(Native Method)
at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:413)
at java.net.ServerSocket.implAccept(ServerSocket.java:243)
at java.net.ServerSocket.accept(ServerSocket.java:222)
at CloseTest.run(CloseTest.java:19)
TOOK TOO LONG TO NOTICE THE INTERRUPT AND/OR CLOSE!!!
(Review ID: 111881)
======================================================================
9 Nov 2000, xxxxx@xxxxx -- recently re-opened as # 4386498.
---------------
java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0)
Java HotSpot(TM) Client VM (build 1.3.0, mixed mode)
This bug looks same as bug ID 4107121. When a ServerSocket is waiting in
accept() on a thread (thread-1), close() on another thread (thread-2) should
close the ServerSocket and cause an IOException on thread-2, but on JDK1.3 for
Linux, close() doesn't take effect; server socket isn't closed.
I tested this with JDK1.2.2_006, JDK1.3.0rc1 and JDK1.3.0. 1.2.2 doesn't have
this probrem. 1.3.0 has it on both of mixed / interpreted mode.
To reproduce, just run following program. On JDK1.2.2, an IOException is raised
when close() is called, but no responce can be seen on 1.3.
import java.net.*;
import java.io.*;
public class Test {
PrintStream out = System.out;
^Z^Z
class ServerThread extends Thread {
ServerSocket serverSocket = null;
void println(String mes) {
out.println("SVR: " + mes);
out.flush();
}
public ServerThread() {
super("ServerThread");
}
public void run() {
println("server thread started.");
try {
println("creating server socket...");
serverSocket = new ServerSocket(2222);
println("...server socket created.");
println("starting accept...");
Socket clientSocket = serverSocket.accept();
println("...accept finished.");
println("closing client socket...");
clientSocket.close();
println("...client socket closed.");
println("closing server socket...");
serverSocket.close();
println("...server socket closed.");
}
catch (IOException ex) {
println("ERROR ::");
ex.printStackTrace(out);
out.flush();
}
println("server thread finished.");
}
}
void println(String mes) {
out.println(mes);
out.flush();
}
public void doit() throws Exception {
ServerThread server = new ServerThread();
server.start();
Thread.currentThread().sleep(1500);
println("closing server socket...");
server.serverSocket.close();
println("...server socket closed.");
Thread.currentThread().sleep(1500);
}
public static void main(String[] args) throws Exception {
Test t = new Test();
t.doit();
}
}
(Review ID: 110961)
======================================================================
Note: if you use jdk1.2.2 from blackdown, there is no bug but if you use either
customer jdk1.3 or SUN jdk1.3 there is a bug.......
Also Note: It all works under windows (jdk1.3)
Hint: maybe some synchronized code in native impl of Socket (there seems to have
been a similar bug in the past: blocking socket methods and close methods were
synchronized)
Now here is the code:
import java.io.*;
import java.net.*;
public
class Bug
{
//--------------------------------------------------------------------
// public
//--------------------------------------------------------------------
public Bug()
{
theAcceptingThread = new Thread("acceptor")
{
public void
run()
{
try
{
theSocket = new ServerSocket(1234);
theSocket.accept();
}
catch (IOException anException)
{
System.out.println("ok, this is what should happen " +
"when there is no bug....");
anException.printStackTrace();
}
}
};
theClosingThread = new Thread("closer")
{
public void
run()
{
try
{
theSocket.close();
}
catch (IOException anException)
{
System.out.println("assert!, closing a running " +
"acceptor should not cause problems");
}
}
};
theAcceptingThread.start();
synchronized (this)
{
try
{
wait(5000); // wait 5 secs
}
catch (Exception anException)
{
// empty
}
}
theClosingThread.start();
}
//--------------------------------------------------------------------
public static void
main(String[] anArgList)
{
Bug myBug = new Bug();
}
//--------------------------------------------------------------------
// members
//--------------------------------------------------------------------
private ServerSocket theSocket;
private Thread theAcceptingThread;
private Thread theClosingThread;
}
(Review ID: 109055)
======================================================================
|
|
Comments
|
Submitted On 26-NOV-2000
gregwilkins
So sun are saying that Thread.stop is depreciated and
Thread.interrupt
can't be relied on. And on Linux close is not preemptive so
how are you
meant to stop an accepting thread?
How does the IBM JDK manage to do this if it is a Linux
problem?
Why does sun 1.2 JDK not suffer from this problem?
Submitted On 20-AUG-2001
sbrnet
well, here is a work around for you which actually works
fine. But is very ugly. Just create a fake Socket connection
to your serversocket and before you start handling the
socket check if by boolean value or something like that, if
the serversocket has been closed.
PLEASE NOTE: JDK6 is formerly known as Project Mustang
|