dev@grizzly.java.net

Infinite loop occurs in SelectorHandlerStateTest

From: Bongjae Chang <carryel_at_korea.com>
Date: Sat, 27 Jun 2009 13:42:44 +0900

Hi,

When I tested SelectorHandlerStateTest, sometimes I met infinite loop.

Here is a log.
---
Running com.sun.grizzly.SelectorHandlerStateTest
2009. 6. 27 ¿ÀÈÄ 1:04:58 com.sun.grizzly.Controller start
Á¤º¸: Starting Grizzly Framework 1.9.17-SNAPSHOT - Sat Jun 27 13:04:58 KST 2009
2009. 6. 27 ¿ÀÈÄ 1:04:59 com.sun.grizzly.TCPSelectorHandler acceptWithoutRegistration
°æ°í: null
2009. 6. 27 ¿ÀÈÄ 1:05:00 com.sun.grizzly.TCPSelectorHandler acceptWithoutRegistration
°æ°í: null
2009. 6. 27 ¿ÀÈÄ 1:05:01 com.sun.grizzly.TCPSelectorHandler acceptWithoutRegistration
°æ°í: null
2009. 6. 27 ¿ÀÈÄ 1:05:02 com.sun.grizzly.TCPSelectorHandler acceptWithoutRegistration
°æ°í: null
2009. 6. 27 ¿ÀÈÄ 1:05:03 com.sun.grizzly.TCPSelectorHandler acceptWithoutRegistration
°æ°í: null
2009. 6. 27 ¿ÀÈÄ 1:05:04 com.sun.grizzly.TCPSelectorHandler acceptWithoutRegistration
°æ°í: null
2009. 6. 27 ¿ÀÈÄ 1:05:05 com.sun.grizzly.TCPSelectorHandler acceptWithoutRegistration
°æ°í: null
2009. 6. 27 ¿ÀÈÄ 1:05:06 com.sun.grizzly.TCPSelectorHandler acceptWithoutRegistration
°æ°í: null
2009. 6. 27 ¿ÀÈÄ 1:05:07 com.sun.grizzly.TCPSelectorHandler acceptWithoutRegistration
°æ°í: null
2009. 6. 27 ¿ÀÈÄ 1:05:08 com.sun.grizzly.TCPSelectorHandler acceptWithoutRegistration
°æ°í: null
...
---
("°æ°í" means "warning")

This seems rev.3394's regression( Grizzly issue #642, https://grizzly.dev.java.net/issues/show_bug.cgi?id=642, "Temporary problem makes grizzly crash permanently" )

I printed the exception. Here is a log.
---
java.nio.channels.ClosedChannelException
 at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:130)
 at com.sun.grizzly.TCPSelectorHandler.acceptWithoutRegistration(TCPSelectorHandler.java:788)
 at com.sun.grizzly.RoundRobinSelectorHandler.onAcceptInterest(RoundRobinSelectorHandler.java:87)
 at com.sun.grizzly.SelectorHandlerRunner.handleSelectedKey(SelectorHandlerRunner.java:289)
 at com.sun.grizzly.SelectorHandlerRunner.handleSelectedKeys(SelectorHandlerRunner.java:257)
 at com.sun.grizzly.SelectorHandlerRunner.doSelect(SelectorHandlerRunner.java:194)
 at com.sun.grizzly.SelectorHandlerRunner.run(SelectorHandlerRunner.java:129)
 at com.sun.grizzly.util.FixedThreadPool$BasicWorker.dowork(FixedThreadPool.java:379)
 at com.sun.grizzly.util.FixedThreadPool$BasicWorker.run(FixedThreadPool.java:360)
 at java.lang.Thread.run(Thread.java:619)
2009. 6. 27 ¿ÀÈÄ 1:30:30 com.sun.grizzly.TCPSelectorHandler acceptWithoutRegistration
°æ°í: null
java.nio.channels.ClosedChannelException
 at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:130)
 at com.sun.grizzly.TCPSelectorHandler.acceptWithoutRegistration(TCPSelectorHandler.java:788)
 at com.sun.grizzly.TCPSelectorHandler.acceptWithoutRegistration(TCPSelectorHandler.java:798)
 at com.sun.grizzly.RoundRobinSelectorHandler.onAcceptInterest(RoundRobinSelectorHandler.java:87)
 at com.sun.grizzly.SelectorHandlerRunner.handleSelectedKey(SelectorHandlerRunner.java:289)
 at com.sun.grizzly.SelectorHandlerRunner.handleSelectedKeys(SelectorHandlerRunner.java:257)
 at com.sun.grizzly.SelectorHandlerRunner.doSelect(SelectorHandlerRunner.java:194)
 at com.sun.grizzly.SelectorHandlerRunner.run(SelectorHandlerRunner.java:129)
 at com.sun.grizzly.util.FixedThreadPool$BasicWorker.dowork(FixedThreadPool.java:379)
 at com.sun.grizzly.util.FixedThreadPool$BasicWorker.run(FixedThreadPool.java:360)
 at java.lang.Thread.run(Thread.java:619)
2009. 6. 27 ¿ÀÈÄ 1:30:31 com.sun.grizzly.TCPSelectorHandler acceptWithoutRegistration
°æ°í: null
---

I think that maybe TCPSelectorHandler#acceptWithoutRegistration() should be modified like the following.

This is a sample patch.
---
Index: com/sun/grizzly/TCPSelectorHandler.java
===================================================================
--- com/sun/grizzly/TCPSelectorHandler.java (revision 3397)
+++ com/sun/grizzly/TCPSelectorHandler.java (working copy)
@@ -787,6 +787,8 @@
         try{
             return ((ServerSocketChannel) key.channel()).accept();
         } catch (IOException ex){
+ if(!key.isValid())
+ throw ex;
             try {
                 // Let's try to recover here from too many open file
                 Thread.sleep(1000);

---

But, I think that the recursive method call without max retrial count at rev.3394 is still dangeous.

Thanks.

--
Bongjae Chang