KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > server > ss > provider > ASServerSocket


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23 package com.sun.enterprise.server.ss.provider;
24
25 import java.io.IOException JavaDoc;
26 import java.net.InetAddress JavaDoc;
27 import java.net.InetSocketAddress JavaDoc;
28 import java.net.ServerSocket JavaDoc;
29 import java.net.Socket JavaDoc;
30 import java.net.SocketAddress JavaDoc;
31 import java.net.SocketException JavaDoc;
32 import java.nio.channels.ServerSocketChannel JavaDoc;
33 import java.nio.channels.spi.SelectorProvider JavaDoc;
34 import java.util.Iterator JavaDoc;
35 import java.util.LinkedList JavaDoc;
36 import java.util.logging.Level JavaDoc;
37 import java.util.logging.Logger JavaDoc;
38
39 import com.sun.enterprise.server.ss.spi.ASSocketFacadeUtils;
40 import com.sun.logging.LogDomains;
41
42 /**
43  * Wrapper for the ServerSocket returned from ServerSocketChannel
44  */

45 public class ASServerSocket extends ServerSocket JavaDoc {
46
47     private static Logger JavaDoc logger = LogDomains.getLogger(LogDomains.CORE_LOGGER);
48
49     private ServerSocket JavaDoc ss = null;
50     private ASServerSocketChannel sschan = null;
51     private boolean toBind = true;
52     private LinkedList JavaDoc socketCache = null;
53     private LinkedList JavaDoc clientSocketLocalPorts = new LinkedList JavaDoc();
54
55     ASServerSocket(ServerSocket JavaDoc ss, ASServerSocketChannel sschan)
56         throws IOException JavaDoc {
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 JavaDoc {
67         return ss.getReceiveBufferSize();
68     }
69
70     public synchronized int getSoTimeout() throws IOException JavaDoc {
71         return ss.getSoTimeout();
72     }
73
74     public void close() throws IOException JavaDoc {
75         ASSocketFacadeUtils.getASSocketService().close(getLocalPort(), ss,
76         (ServerSocketChannel JavaDoc) sschan.getActualChannel());
77     }
78
79     public boolean getReuseAddress() throws SocketException JavaDoc {
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 JavaDoc {
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 JavaDoc {
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 JavaDoc {
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 JavaDoc toString() {
116         return ss.toString();
117     }
118
119     public InetAddress JavaDoc getInetAddress() {
120         return ss.getInetAddress();
121     }
122
123     /**
124      * Logic of accept method:
125      *
126      * When any appserver service do a serversocket.accept(), it will
127      * reach the following method.
128      *
129      * 1. Try to get a socket from its cache, for a client in same VM.
130      * 2. Get the first socket in the cache.
131      * 3. If there is nothing in the socket cache, do an actual accept
132      * This is the most common case. The first ever accept will
133      * do ss.accept()
134      * 4. If clientSocketLocalPorts empty (i.e there is no request waiting
135      * in the same VM) then do ASSocketService.waitOnAccept. waitOnAccept
136      * will block until server startup or until connection request from
137      * within the same VM.
138      * 5. There is a socket connection request waiting on the same VM. So
139      * we need to accept that request. Find for that socket.
140      */

141     public synchronized Socket JavaDoc accept() throws IOException JavaDoc {
142
143         Socket JavaDoc s = getAlreadyAcceptedSocketInSameVM();
144
145
146         if ( s != null) { // Comment 1.
147
return s;
148         } else {
149            s = getFirstSocketFromCache(); // Comment 2.
150
}
151
152
153         if (s == null) {
154             s = acceptSocket(); // Comment 3.
155
}
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) { // Comment 4.
163
ASSocketFacadeUtils.getASSocketService().waitOnAccept(s);
164         }
165
166         if (hasClientSocketLocalPorts()) { //Comment 5
167
s = findSocketInSameVM(s);
168         }
169
170         return s;
171     }
172
173     private Socket JavaDoc acceptSocket() throws IOException JavaDoc {
174         return ss.accept();
175     }
176
177     public void addClientSocketLocalPort(int port) {
178         synchronized (clientSocketLocalPorts) {
179             clientSocketLocalPorts.addLast(new Integer JavaDoc(port));
180         }
181     }
182
183     public boolean hasClientSocketLocalPorts() {
184         return clientSocketLocalPorts.size() > 0;
185     }
186
187     /**
188      * 1. If socket cache is null or empty return null.
189      * 2. If there is more than one socket in the cache and
190      * clientSocketLocalPorts is not empty then try to find the
191      * socket in the cache that has client request. Then return it.
192      */

193     private Socket JavaDoc getAlreadyAcceptedSocketInSameVM() {
194         if (socketCache != null) {
195             if (socketCache.size() > 0 && clientSocketLocalPorts.size() > 0) {
196                 Iterator JavaDoc it = socketCache.iterator();
197                 Socket JavaDoc result = null;
198                 while (it.hasNext()) {
199                     result = (Socket JavaDoc) it.next();
200                     if ( ASSocketFacadeUtils.getASSocketService().isLocalClient(result) ) {
201                         Integer JavaDoc port = new Integer JavaDoc(result.getPort());
202                         synchronized (clientSocketLocalPorts) {
203                             if (clientSocketLocalPorts.remove(port)) {
204                                it.remove();
205                                return result; // Comment 2.
206
}
207                         }
208                     }
209                 }
210             }
211         }
212         return null; // Comment 1.
213
}
214
215     /**
216      * 1. return the first socket in the cache.
217      */

218     private Socket JavaDoc getFirstSocketFromCache() {
219         if (socketCache != null && socketCache.size() > 0 ) {
220             return (Socket JavaDoc) socketCache.removeFirst(); // Comment 3, 4
221
} else {
222             return null;
223         }
224     }
225
226     private LinkedList JavaDoc getSocketCache() {
227         if (socketCache == null) {
228             socketCache = new LinkedList JavaDoc();
229         }
230         return socketCache;
231     }
232
233     /**
234      * If the clientSocketLocalPorts table contains the local port,
235      * of the socket, then return that. Otherwise loop until such
236      * socket is accepted.
237      */

238     private Socket JavaDoc findSocketInSameVM(Socket JavaDoc s) throws IOException JavaDoc {
239         Socket JavaDoc result = s;
240         while (true) {
241             if ( ASSocketFacadeUtils.getASSocketService().isLocalClient(result) ) {
242                 Integer JavaDoc port = new Integer JavaDoc(result.getPort());
243                 synchronized (clientSocketLocalPorts) {
244                     if (clientSocketLocalPorts.remove(port)) {
245                         break;
246                     }
247                 }
248             }
249
250             LinkedList JavaDoc cache = getSocketCache();
251             cache.addLast(result);
252             result = acceptSocket();
253         }
254         return result;
255     }
256
257     public SocketAddress JavaDoc getLocalSocketAddress() {
258         return ss.getLocalSocketAddress();
259     }
260
261     public void bind(SocketAddress JavaDoc s) throws IOException JavaDoc {
262     // 0 for backlog results in default value being used
263
this.bind(s, 0);
264     }
265
266     public void bind(SocketAddress JavaDoc s, int backlog) throws IOException JavaDoc {
267
268     int port = ((InetSocketAddress JavaDoc)s).getPort();
269
270         if ( logger.isLoggable(Level.FINER) ) {
271          logger.log(Level.FINER, "In ASServerSocket.bind for port " + port,
272            new Exception JavaDoc());
273         }
274
275         sschan.setPortNumber(port);
276
277         if (!ASSocketFacadeUtils.getASSocketService().exists(port)) {
278             ss.bind(s, backlog);
279     }
280     else { // this port is managed by the ASSocketService
281
ServerSocket JavaDoc savedss = getServerSocket(port);
282         if (savedss != null) {
283         // replace the ServerSocketChannel and ServerSocket with the
284
// ones created for this port at startup time.
285
ss = savedss;
286         sschan.setServerSocketChannel(ss.getChannel());
287         }
288
289         int state = getPortState(port);
290         if (state != ASSelectorProvider.PORT_BOUND) {
291         // This may cause an exception if there is a port conflict
292
ss.bind(s, backlog);
293         } else if (state == ASSelectorProvider.PORT_BOUND) {
294                 // The real listener is up. No need for the old listener.
295
ASSocketFacadeUtils.getASSocketService().
296                                                  removeListeningSelector(port);
297             }
298
299         // set the ServerSocket and update the state for this port
300
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 JavaDoc getChannel() {
308          return sschan;
309     }
310
311     private ServerSocket JavaDoc getServerSocket(int port) {
312         ASSelectorProvider provider =
313         (ASSelectorProvider) SelectorProvider.provider();
314         return provider.getServerSocket(port);
315     }
316
317     private void setServerSocket(ServerSocket JavaDoc 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