You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@harmony.apache.org by Charles Lee <li...@gmail.com> on 2009/06/11 07:28:16 UTC

Problems about socket hang methods

Given the test case [1], on linux,  RI will throw a SocketException but
harmony is hanging forever. The problem is from such situation:
1. A fd is used by a slow api, such as read for example.
2. Another thread close the same fd.

Our api will hang forever, because we do not have any way to inform the slow
api that the fd is closed.
1. Do we have api to know this?
2. Is signal a way to solve this? If yes, more concern about this:
    i. Can we use all the real-time signals? For drlvm, I know it uses
SIGUSR2 for gc, any other signal it will use? For vme, no signal it uses, am
I right?
    ii. If we use signal, we need to know the exact process id which is
using the same fd, or we will miss-fire other process to close the read for
example.

Any other ideas about this?

[1]:
public class SocketHangTest {
    private Socket socket;
    private ServerSocket server;
    private SocketAddress localAddress;

    public SocketHangTest() {}

    public void hang() throws Exception{
        server = new ServerSocket(0);
        int port = server.getLocalPort();
        socket = new Socket();
        localAddress = new InetSocketAddress("127.0.0.1", port);

        new Thread() {
            public void run() {
                try {
                    Thread.sleep(1000*5);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                try {
                    System.out.println("Connecting to local host .....");
                    socket.connect(localAddress, 5000);
                    System.out.println("Reading ....");
                    InputStream input = socket.getInputStream();
                    input.read();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }.start();

        server.accept();
        System.out.println("After accepting ...");
        Thread.sleep(1000);
        socket.close();
    }

    public static void main(String[] args) throws Exception{
        SocketHangTest test = new SocketHangTest();
        test.hang();
    }
}



-- 
Yours sincerely,
Charles Lee

Re: Problems about socket hang methods

Posted by Regis <xu...@gmail.com>.
Jimmy,Jing Lv wrote:
> Hi Charles,
> 
>      As I see the problem was that when you try to close a Socket on Linux,
> the underlay socket was closed however it won't wake up the blocking reading
> operation. This is an known issue for Linux API.
>      An easy way to fix such problems is to make the socket waiting on
> selection rather than blocking on reading( If selection itself cannot be
> waken up by closing on some platform, we may divide the selection, e.g 10ms
> once, check if fd is closed when one selection is over. If I remember
> correctly some of the Harmony operation has been fixed with this solution
> but it seems there may be some more. Note I remember such problem does not
> appear on Windows.

It is an easy way, but introduce at least one "select" overhead for every 
blocking operations, when these operations are frequent, the overhead can't be 
ignored.

> 
>      I guess signal may not work for the blocking reading operation and it's
> much more complex.
> 
> 2009/6/11 Charles Lee <li...@gmail.com>
> 
>> Given the test case [1], on linux,  RI will throw a SocketException but
>> harmony is hanging forever. The problem is from such situation:
>> 1. A fd is used by a slow api, such as read for example.
>> 2. Another thread close the same fd.
>>
>> Our api will hang forever, because we do not have any way to inform the
>> slow
>> api that the fd is closed.
>> 1. Do we have api to know this?
>> 2. Is signal a way to solve this? If yes, more concern about this:
>>    i. Can we use all the real-time signals? For drlvm, I know it uses
>> SIGUSR2 for gc, any other signal it will use? For vme, no signal it uses,
>> am
>> I right?
>>    ii. If we use signal, we need to know the exact process id which is
>> using the same fd, or we will miss-fire other process to close the read for
>> example.
>>
>> Any other ideas about this?
>>
>> [1]:
>> public class SocketHangTest {
>>    private Socket socket;
>>    private ServerSocket server;
>>    private SocketAddress localAddress;
>>
>>    public SocketHangTest() {}
>>
>>    public void hang() throws Exception{
>>        server = new ServerSocket(0);
>>        int port = server.getLocalPort();
>>        socket = new Socket();
>>        localAddress = new InetSocketAddress("127.0.0.1", port);
>>
>>        new Thread() {
>>            public void run() {
>>                try {
>>                    Thread.sleep(1000*5);
>>                } catch (InterruptedException e) {
>>                    // TODO Auto-generated catch block
>>                    e.printStackTrace();
>>                }
>>                try {
>>                    System.out.println("Connecting to local host .....");
>>                    socket.connect(localAddress, 5000);
>>                    System.out.println("Reading ....");
>>                    InputStream input = socket.getInputStream();
>>                    input.read();
>>                } catch (IOException e) {
>>                    // TODO Auto-generated catch block
>>                    e.printStackTrace();
>>                }
>>            }
>>        }.start();
>>
>>        server.accept();
>>        System.out.println("After accepting ...");
>>        Thread.sleep(1000);
>>        socket.close();
>>    }
>>
>>    public static void main(String[] args) throws Exception{
>>        SocketHangTest test = new SocketHangTest();
>>        test.hang();
>>    }
>> }
>>
>>
>>
>> --
>> Yours sincerely,
>> Charles Lee
>>
> 
> 
> 


-- 
Best Regards,
Regis.

Re: Problems about socket hang methods

Posted by "Jimmy,Jing Lv" <fi...@gmail.com>.
Hi Charles,

     As I see the problem was that when you try to close a Socket on Linux,
the underlay socket was closed however it won't wake up the blocking reading
operation. This is an known issue for Linux API.
     An easy way to fix such problems is to make the socket waiting on
selection rather than blocking on reading( If selection itself cannot be
waken up by closing on some platform, we may divide the selection, e.g 10ms
once, check if fd is closed when one selection is over. If I remember
correctly some of the Harmony operation has been fixed with this solution
but it seems there may be some more. Note I remember such problem does not
appear on Windows.

     I guess signal may not work for the blocking reading operation and it's
much more complex.

2009/6/11 Charles Lee <li...@gmail.com>

> Given the test case [1], on linux,  RI will throw a SocketException but
> harmony is hanging forever. The problem is from such situation:
> 1. A fd is used by a slow api, such as read for example.
> 2. Another thread close the same fd.
>
> Our api will hang forever, because we do not have any way to inform the
> slow
> api that the fd is closed.
> 1. Do we have api to know this?
> 2. Is signal a way to solve this? If yes, more concern about this:
>    i. Can we use all the real-time signals? For drlvm, I know it uses
> SIGUSR2 for gc, any other signal it will use? For vme, no signal it uses,
> am
> I right?
>    ii. If we use signal, we need to know the exact process id which is
> using the same fd, or we will miss-fire other process to close the read for
> example.
>
> Any other ideas about this?
>
> [1]:
> public class SocketHangTest {
>    private Socket socket;
>    private ServerSocket server;
>    private SocketAddress localAddress;
>
>    public SocketHangTest() {}
>
>    public void hang() throws Exception{
>        server = new ServerSocket(0);
>        int port = server.getLocalPort();
>        socket = new Socket();
>        localAddress = new InetSocketAddress("127.0.0.1", port);
>
>        new Thread() {
>            public void run() {
>                try {
>                    Thread.sleep(1000*5);
>                } catch (InterruptedException e) {
>                    // TODO Auto-generated catch block
>                    e.printStackTrace();
>                }
>                try {
>                    System.out.println("Connecting to local host .....");
>                    socket.connect(localAddress, 5000);
>                    System.out.println("Reading ....");
>                    InputStream input = socket.getInputStream();
>                    input.read();
>                } catch (IOException e) {
>                    // TODO Auto-generated catch block
>                    e.printStackTrace();
>                }
>            }
>        }.start();
>
>        server.accept();
>        System.out.println("After accepting ...");
>        Thread.sleep(1000);
>        socket.close();
>    }
>
>    public static void main(String[] args) throws Exception{
>        SocketHangTest test = new SocketHangTest();
>        test.hang();
>    }
> }
>
>
>
> --
> Yours sincerely,
> Charles Lee
>



-- 

Best Regards!

Jimmy, Jing Lv
China Software Development Lab, IBM