1 17 18 package org.apache.avalon.cornerstone.blocks.connection; 19 20 import java.io.IOException ; 21 import java.io.InterruptedIOException ; 22 import java.net.ServerSocket ; 23 import java.net.Socket ; 24 import java.util.Iterator ; 25 import java.util.List ; 26 import java.util.Vector ; 27 28 import org.apache.avalon.cornerstone.services.connection.ConnectionHandler; 29 import org.apache.avalon.cornerstone.services.connection.ConnectionHandlerFactory; 30 31 import org.apache.excalibur.thread.ThreadPool; 32 import org.apache.avalon.framework.logger.AbstractLogEnabled; 33 34 40 class Connection 41 extends AbstractLogEnabled 42 implements Runnable 43 { 44 private final ServerSocket m_serverSocket; 45 private final ConnectionHandlerFactory m_handlerFactory; 46 private final ThreadPool m_threadPool; 47 private final Vector m_runners = new Vector (); 48 49 private Thread m_thread; 51 52 public Connection( final ServerSocket serverSocket, 53 final ConnectionHandlerFactory handlerFactory, 54 final ThreadPool threadPool ) 55 { 56 m_serverSocket = serverSocket; 57 m_handlerFactory = handlerFactory; 58 m_threadPool = threadPool; 59 } 60 61 public void dispose() 62 throws Exception 63 { 64 synchronized( this ) 65 { 66 if( null != m_thread ) 67 { 68 final Thread thread = m_thread; 69 m_thread = null; 70 thread.interrupt(); 71 72 76 wait( ); 77 } 78 } 79 80 final Iterator runners = m_runners.iterator(); 81 while( runners.hasNext() ) 82 { 83 final ConnectionRunner runner = (ConnectionRunner)runners.next(); 84 runner.dispose(); 85 } 86 87 m_runners.clear(); 88 } 89 90 public void run() 91 { 92 m_thread = Thread.currentThread(); 93 94 while( null != m_thread && !Thread.interrupted() ) 95 { 96 101 try 102 { 103 final Socket socket = m_serverSocket.accept(); 104 final ConnectionRunner runner = 105 new ConnectionRunner( socket, m_runners, m_handlerFactory ); 106 setupLogger( runner ); 107 m_threadPool.execute( runner ); 108 } 109 catch( final InterruptedIOException iioe ) 110 { 111 } 113 catch( final IOException ioe ) 114 { 115 final String message = "Exception accepting connection"; 116 getLogger().error( message, ioe ); 117 } 118 catch( final Exception e ) 119 { 120 final String message = "Exception executing runner"; 121 getLogger().error( message, e ); 122 } 123 } 124 125 synchronized( this ) 126 { 127 notifyAll(); 128 m_thread = null; 129 } 130 } 131 } 132 133 class ConnectionRunner 134 extends AbstractLogEnabled 135 implements Runnable 136 { 137 private Socket m_socket; 138 private Thread m_thread; 139 private List m_runners; 140 private ConnectionHandlerFactory m_handlerFactory; 141 private boolean m_finished; 142 143 ConnectionRunner( final Socket socket, 144 final List runners, 145 final ConnectionHandlerFactory handlerFactory ) 146 { 147 m_socket = socket; 148 m_runners = runners; 149 m_handlerFactory = handlerFactory; 150 } 151 152 public void dispose() 153 throws Exception 154 { 155 synchronized( this ) 156 { 157 m_finished = true; 158 if( null != m_thread ) 159 { 160 m_thread.interrupt(); 161 m_thread = null; 162 166 wait( ); 167 } 168 } 169 } 170 171 public void run() 172 { 173 synchronized( this ) 177 { 178 if( m_finished ) 179 { 180 shutdownSocket(); 181 return; 182 } 183 m_thread = Thread.currentThread(); 184 m_runners.add( this ); 185 } 186 187 ConnectionHandler handler = null; 188 try 189 { 190 debugBanner( true ); 191 192 handler = m_handlerFactory.createConnectionHandler(); 193 handler.handleConnection( m_socket ); 194 195 debugBanner( false ); 196 } 197 catch( final Exception e ) 198 { 199 final String message = "Error handling connection"; 200 getLogger().warn( message, e ); 201 } 202 203 if( null != handler ) 204 { 205 m_handlerFactory.releaseConnectionHandler( handler ); 206 } 207 208 shutdownSocket(); 209 210 synchronized( this ) 213 { 214 m_thread = null; 215 m_runners.remove( this ); 216 217 notifyAll(); 218 } 219 220 } 221 222 228 private void debugBanner( final boolean starting ) 229 { 230 if( getLogger().isDebugEnabled() ) 231 { 232 final String prefix = ( starting ) ? "Starting" : "Ending"; 233 final String message = 234 prefix + " connection on " + 235 m_socket.getInetAddress().getHostAddress(); 236 getLogger().debug( message ); 237 } 238 } 239 240 243 private void shutdownSocket() 244 { 245 try 246 { 247 m_socket.close(); 248 } 249 catch( final IOException ioe ) 250 { 251 final String message = "Error shutting down connection"; 252 getLogger().warn( message, ioe ); 253 } 254 } 255 } 256 | Popular Tags |