remm        2002/10/19 02:30:37

  Modified:    util/java/org/apache/tomcat/util/net PoolTcpEndpoint.java
  Log:
  - Attempts to address bug 13736.
  - Add code for recovery if the serverSocket dies. Needs testing (I tested with
    an exception thrown according to a random value after the socket has been
    accepted, and it *seems* to work).
  - There was similar code in Tomcat 4.0, and it is not needed unless there's
    a huge amount of accepts being made. It is also likely caused by JVM's
    network code deficiencies. If running on Unix without root on 80, recovery is
    not possible.
  
  Revision  Changes    Path
  1.5       +56 -36    
jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/PoolTcpEndpoint.java
  
  Index: PoolTcpEndpoint.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/PoolTcpEndpoint.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- PoolTcpEndpoint.java      16 May 2002 18:57:39 -0000      1.4
  +++ PoolTcpEndpoint.java      19 Oct 2002 09:30:37 -0000      1.5
  @@ -102,6 +102,8 @@
       private static final int BACKLOG = 100;
       private static final int TIMEOUT = 1000;
   
  +    private final Object threadSync = new Object();
  +
       private boolean isPool = true;
   
       private int backlog = BACKLOG;
  @@ -312,11 +314,14 @@
                       s.setSoLinger(true, 0);
                }
                s.close();
  -             //              System.out.println("Closing socket " + port );
  -             serverSocket.close(); // XXX?
            } catch(Exception e) {
                   log("Caught exception trying to unlock accept.", e);
            }
  +         try {
  +             serverSocket.close();
  +         } catch(Exception e) {
  +                log("Caught exception trying to close socket.", e);
  +         }
            serverSocket = null;
        }
       }
  @@ -325,6 +330,7 @@
   
       Socket acceptSocket() {
           Socket accepted = null;
  +
        try {
            if (running) {
                if(null!= serverSocket) {
  @@ -343,48 +349,62 @@
                    if( factory != null && accepted != null)
                        factory.initSocket( accepted );
                }
  -         }       
  +         }
        }
        catch(InterruptedIOException iioe) {
            // normal part -- should happen regularly so
            // that the endpoint can release if the server
            // is shutdown.
        }
  -     catch (SocketException e) {
  +     catch (IOException e) {
  +
  +         if (running) {
   
  -         // TCP stacks can throw SocketExceptions when the client
  -         // disconnects.  We don't want this to shut down the
  -         // endpoint, so ignore it. Is there a more robust
  -         // solution?  Should we compare the message string to
  -         // "Connection reset by peer"?
  -
  -         // socket exceptions just after closing endpoint (when
  -         // running=false) aren't even logged
  -         if (running != false) {
                String msg = sm.getString("endpoint.err.nonfatal",
                                          serverSocket, e);
  -             log(msg, e, Log.INFORMATION);
  -         }
  +             log(msg, e, Log.ERROR);
   
  -     } 
  -     
  -     // Future developers: if you identify any other nonfatal
  -     // exceptions, catch them here and log as above
  +                if (accepted != null) {
  +                    try {
  +                        accepted.close();
  +                        accepted = null;
  +                    } catch(Exception ex) {
  +                        msg = sm.getString("endpoint.err.nonfatal",
  +                                           accepted, ex);
  +                        log(msg, ex, Log.INFORMATION);
  +                    }
  +                }
  +                // Restart endpoint when getting an IOException during accept
  +                synchronized (threadSync) {
  +                    try {
  +                        serverSocket.close();
  +                    } catch(Exception ex) {
  +                        msg = sm.getString("endpoint.err.nonfatal",
  +                                           serverSocket, ex);
  +                        log(msg, ex, Log.INFORMATION);
  +                    }
  +                    serverSocket = null;
  +                    try {
  +                        if (inet == null) {
  +                            serverSocket = factory.createSocket(port, backlog);
  +                        } else {
  +                            serverSocket = 
  +                                factory.createSocket(port, backlog, inet);
  +                        }
  +                        if (serverTimeout >= 0)
  +                            serverSocket.setSoTimeout(serverTimeout);
  +                    } catch (Throwable t) {
  +                        msg = sm.getString("endpoint.err.fatal", 
  +                                           serverSocket, t);
  +                        log(msg, t, Log.ERROR);
  +                        stopEndpoint();
  +                    }
  +                }
   
  -     catch(Throwable e) {
  -            // If we are running with a SecurityManager, don't shutdown Socket      
  
  -            // on an AccessControlException.
  -         if( e.getClass().getName().equals("java.security.AccessControlException") 
) {
  -             String msg = "Socket: "+ serverSocket + " AccessControlException: " + 
e.toString();
  -             log(msg, Log.ERROR);
  -         } else {
  -             String msg = sm.getString("endpoint.err.fatal",
  -                                     serverSocket, e);    
  -             log(msg, e, Log.ERROR);
  -             stopEndpoint(); // safe to call this from inside thread pool?
  -         }
  -     }
  +            }
   
  +     }
  +     
        return accepted;
       }
   
  @@ -483,7 +503,7 @@
                s = endpoint.acceptSocket();
            } catch (Throwable t) {
                endpoint.log("Exception in acceptSocket", t);
  -         }           
  +         }
            if(null != s) {
                // Continue accepting on another thread...
                endpoint.tp.runIt(this);
  
  
  

--
To unsubscribe, e-mail:   <mailto:tomcat-dev-unsubscribe@;jakarta.apache.org>
For additional commands, e-mail: <mailto:tomcat-dev-help@;jakarta.apache.org>

Reply via email to