Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 4386498
Votes 0
Synopsis ServerSocket.accept does not detect interrup or close
Category java:classes_net
Reported Against 1.3 , kest-linux-fcs
Release Fixed
State 11-Closed, duplicate of 4344135, bug
Priority: 3-Medium
Related Bugs 4344135
Submit Date 06-NOV-2000
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)
======================================================================
Work Around




Use the IBM JVM - sorry :-)  Or sun 1.2.2
======================================================================
Evaluation
Interruptable I/O has been removed from HotSpot Linux. Given
the general problems with Thread.interrupt developers shouldn't
rely on it (for example on Windows Thread.interrupt never unblocked
networking of file I/O methods). 

However close not being preemptive is a bug on Linux. This requires
changes to HotSpot/Linux's HPI implementation and is being dealt with
in 4344135. Based on this I am closing this bug as a duplicate of
4344135. 

  xxxxx@xxxxx   2000-11-23
Comments
  
  Include a link with my name & email   

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