1 23 package com.sun.enterprise.server.ss.provider; 24 25 import java.io.IOException ; 26 import java.net.InetAddress ; 27 import java.net.InetSocketAddress ; 28 import java.net.ServerSocket ; 29 import java.net.Socket ; 30 import java.net.SocketAddress ; 31 import java.net.SocketException ; 32 import java.nio.channels.ServerSocketChannel ; 33 import java.nio.channels.spi.SelectorProvider ; 34 import java.util.Iterator ; 35 import java.util.LinkedList ; 36 import java.util.logging.Level ; 37 import java.util.logging.Logger ; 38 39 import com.sun.enterprise.server.ss.spi.ASSocketFacadeUtils; 40 import com.sun.logging.LogDomains; 41 42 45 public class ASServerSocket extends ServerSocket { 46 47 private static Logger logger = LogDomains.getLogger(LogDomains.CORE_LOGGER); 48 49 private ServerSocket ss = null; 50 private ASServerSocketChannel sschan = null; 51 private boolean toBind = true; 52 private LinkedList socketCache = null; 53 private LinkedList clientSocketLocalPorts = new LinkedList (); 54 55 ASServerSocket(ServerSocket ss, ASServerSocketChannel sschan) 56 throws IOException { 57 this.ss = ss; 58 this.sschan = sschan; 59 } 60 61 public int getLocalPort() { 62 return ss.getLocalPort(); 63 } 64 65 public synchronized int getReceiveBufferSize() 66 throws SocketException { 67 return ss.getReceiveBufferSize(); 68 } 69 70 public synchronized int getSoTimeout() throws IOException { 71 return ss.getSoTimeout(); 72 } 73 74 public void close() throws IOException { 75 ASSocketFacadeUtils.getASSocketService().close(getLocalPort(), ss, 76 (ServerSocketChannel ) sschan.getActualChannel()); 77 } 78 79 public boolean getReuseAddress() throws SocketException { 80 return ss.getReuseAddress(); 81 } 82 83 public boolean isBound() { 84 return ss.isBound(); 85 } 86 87 public boolean isClosed() { 88 return ss.isClosed(); 89 } 90 91 public synchronized void setReceiveBufferSize(int i) 92 throws SocketException { 93 if ( logger.isLoggable(Level.FINE) ) { 94 logger.fine("In ASServerSocket.setReceiveBufferSize = "+i); 95 } 96 ss.setReceiveBufferSize(i); 97 } 98 99 public synchronized void setSoTimeout(int i) 100 throws SocketException { 101 if ( logger.isLoggable(Level.FINE) ) { 102 logger.fine("In ASServerSocket.setSoTimeout = "+i); 103 } 104 ss.setSoTimeout(i); 105 } 106 107 public void setReuseAddress(boolean b) 108 throws SocketException { 109 if ( logger.isLoggable(Level.FINE) ) { 110 logger.fine("In ASServerSocket.setReuseAddress = "+b); 111 } 112 ss.setReuseAddress(b); 113 } 114 115 public java.lang.String toString() { 116 return ss.toString(); 117 } 118 119 public InetAddress getInetAddress() { 120 return ss.getInetAddress(); 121 } 122 123 141 public synchronized Socket accept() throws IOException { 142 143 Socket s = getAlreadyAcceptedSocketInSameVM(); 144 145 146 if ( s != null) { return s; 148 } else { 149 s = getFirstSocketFromCache(); } 151 152 153 if (s == null) { 154 s = acceptSocket(); } 156 157 if ( logger.isLoggable(Level.FINE) ) { 158 logger.fine("In ASServerSocket.accept got connection, s.port=" 159 +s.getPort()+" s.localPort="+s.getLocalPort()); 160 } 161 162 if ( hasClientSocketLocalPorts() == false) { ASSocketFacadeUtils.getASSocketService().waitOnAccept(s); 164 } 165 166 if (hasClientSocketLocalPorts()) { s = findSocketInSameVM(s); 168 } 169 170 return s; 171 } 172 173 private Socket acceptSocket() throws IOException { 174 return ss.accept(); 175 } 176 177 public void addClientSocketLocalPort(int port) { 178 synchronized (clientSocketLocalPorts) { 179 clientSocketLocalPorts.addLast(new Integer (port)); 180 } 181 } 182 183 public boolean hasClientSocketLocalPorts() { 184 return clientSocketLocalPorts.size() > 0; 185 } 186 187 193 private Socket getAlreadyAcceptedSocketInSameVM() { 194 if (socketCache != null) { 195 if (socketCache.size() > 0 && clientSocketLocalPorts.size() > 0) { 196 Iterator it = socketCache.iterator(); 197 Socket result = null; 198 while (it.hasNext()) { 199 result = (Socket ) it.next(); 200 if ( ASSocketFacadeUtils.getASSocketService().isLocalClient(result) ) { 201 Integer port = new Integer (result.getPort()); 202 synchronized (clientSocketLocalPorts) { 203 if (clientSocketLocalPorts.remove(port)) { 204 it.remove(); 205 return result; } 207 } 208 } 209 } 210 } 211 } 212 return null; } 214 215 218 private Socket getFirstSocketFromCache() { 219 if (socketCache != null && socketCache.size() > 0 ) { 220 return (Socket ) socketCache.removeFirst(); } else { 222 return null; 223 } 224 } 225 226 private LinkedList getSocketCache() { 227 if (socketCache == null) { 228 socketCache = new LinkedList (); 229 } 230 return socketCache; 231 } 232 233 238 private Socket findSocketInSameVM(Socket s) throws IOException { 239 Socket result = s; 240 while (true) { 241 if ( ASSocketFacadeUtils.getASSocketService().isLocalClient(result) ) { 242 Integer port = new Integer (result.getPort()); 243 synchronized (clientSocketLocalPorts) { 244 if (clientSocketLocalPorts.remove(port)) { 245 break; 246 } 247 } 248 } 249 250 LinkedList cache = getSocketCache(); 251 cache.addLast(result); 252 result = acceptSocket(); 253 } 254 return result; 255 } 256 257 public SocketAddress getLocalSocketAddress() { 258 return ss.getLocalSocketAddress(); 259 } 260 261 public void bind(SocketAddress s) throws IOException { 262 this.bind(s, 0); 264 } 265 266 public void bind(SocketAddress s, int backlog) throws IOException { 267 268 int port = ((InetSocketAddress )s).getPort(); 269 270 if ( logger.isLoggable(Level.FINER) ) { 271 logger.log(Level.FINER, "In ASServerSocket.bind for port " + port, 272 new Exception ()); 273 } 274 275 sschan.setPortNumber(port); 276 277 if (!ASSocketFacadeUtils.getASSocketService().exists(port)) { 278 ss.bind(s, backlog); 279 } 280 else { ServerSocket savedss = getServerSocket(port); 282 if (savedss != null) { 283 ss = savedss; 286 sschan.setServerSocketChannel(ss.getChannel()); 287 } 288 289 int state = getPortState(port); 290 if (state != ASSelectorProvider.PORT_BOUND) { 291 ss.bind(s, backlog); 293 } else if (state == ASSelectorProvider.PORT_BOUND) { 294 ASSocketFacadeUtils.getASSocketService(). 296 removeListeningSelector(port); 297 } 298 299 setServerSocket(ss, port); 301 } 302 if ( logger.isLoggable(Level.FINE) ) { 303 logger.fine("In ASServerSocket.bind, bound at port " + ss.getLocalPort()); 304 } 305 } 306 307 public ServerSocketChannel getChannel() { 308 return sschan; 309 } 310 311 private ServerSocket getServerSocket(int port) { 312 ASSelectorProvider provider = 313 (ASSelectorProvider) SelectorProvider.provider(); 314 return provider.getServerSocket(port); 315 } 316 317 private void setServerSocket(ServerSocket ss, int port) { 318 ASSelectorProvider provider = 319 (ASSelectorProvider) SelectorProvider.provider(); 320 provider.setServerSocket(ss, port); 321 } 322 323 private int getPortState(int port) { 324 ASSelectorProvider provider = 325 (ASSelectorProvider) SelectorProvider.provider(); 326 return provider.getPortState(port); 327 } 328 329 } 330 331 | Popular Tags |