001: /*
002: * Copyright (c) 2000 by Matt Welsh and The Regents of the University of
003: * California. All rights reserved.
004: *
005: * Permission to use, copy, modify, and distribute this software and its
006: * documentation for any purpose, without fee, and without written agreement is
007: * hereby granted, provided that the above copyright notice and the following
008: * two paragraphs appear in all copies of this software.
009: *
010: * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
011: * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
012: * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
013: * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
014: *
015: * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
016: * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
017: * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
018: * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
019: * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
020: *
021: * Author: Matt Welsh <mdw@cs.berkeley.edu>
022: *
023: */
024:
025: package seda.sandStorm.lib.aSocket.nbio;
026:
027: import seda.sandStorm.api.*;
028: import seda.sandStorm.core.*;
029: import seda.sandStorm.lib.aSocket.*;
030: import seda.nbio.*;
031:
032: import java.net.*;
033: import java.io.*;
034: import java.util.*;
035:
036: /**
037: * Internal class used to represent a server socket listening on a
038: * given port.
039: */
040: public class ListenSockState extends
041: seda.sandStorm.lib.aSocket.ListenSockState {
042:
043: private static final boolean DEBUG = false;
044:
045: NonblockingServerSocket nbservsock;
046: private SelectItem si;
047: private SelectSource listen_selsource;
048:
049: public ListenSockState(ATcpListenRequest req,
050: SelectSourceIF listen_selsource) throws IOException {
051: this (req);
052: this .listen_selsource = (SelectSource) listen_selsource;
053: System.out.println("nbservsock = " + nbservsock);
054: si = new SelectItem(nbservsock, this , Selectable.ACCEPT_READY);
055: listen_selsource.register(si);
056: }
057:
058: ListenSockState(ATcpListenRequest req) throws IOException {
059: this .port = req.port;
060: this .compQ = req.compQ;
061: this .writeClogThreshold = req.writeClogThreshold;
062: if (DEBUG)
063: System.err
064: .println("ListenThread: Creating nbservsock on port "
065: + port);
066:
067: this .servsock = req.servsock;
068: try {
069: nbservsock = new NonblockingServerSocket(port);
070: } catch (IOException ioe) {
071: // Can't create socket - probably because the address was
072: // already in use
073: ATcpListenFailedEvent ev = new ATcpListenFailedEvent(
074: servsock, ioe.getMessage());
075: compQ.enqueue_lossy(ev);
076: return;
077: }
078: this .servsock.lss = this ;
079: compQ.enqueue_lossy(new ATcpListenSuccessEvent(servsock));
080: }
081:
082: protected Socket accept() throws IOException {
083: if (nbservsock == null)
084: return null; // If already closed
085: NonblockingSocket nbsock;
086: try {
087: if (DEBUG)
088: System.err.println("LSS: Calling nbservsock.nbAccept");
089: nbsock = nbservsock.nbAccept();
090: if (DEBUG)
091: System.err.println("LSS: nbservsock.nbAccept returned "
092: + nbsock);
093: } catch (SocketException e) {
094: // Assume this is a 'Too many open files' exception
095: // XXX Probably want to throttle the listenthread somehow?
096: if (DEBUG)
097: System.err
098: .println("LSS: nbservsock.nbAccept got SocketException "
099: + e);
100: return null;
101:
102: } catch (IOException e) {
103: System.err.println("LSS: nbAccept got IOException: " + e);
104: e.printStackTrace();
105:
106: ATcpServerSocketClosedEvent dead = new ATcpServerSocketClosedEvent(
107: servsock);
108: compQ.enqueue_lossy(dead);
109: // Deregister
110: listen_selsource.deregister(si);
111: throw e;
112: }
113:
114: return nbsock;
115: }
116:
117: protected void suspend() {
118: if (nbservsock == null)
119: return; // If already closed
120: System.err.println("LSS: Suspending accept on " + servsock);
121: si.events &= ~(Selectable.ACCEPT_READY);
122: listen_selsource.update(si);
123: }
124:
125: protected void resume() {
126: if (nbservsock == null)
127: return; // If already closed
128: System.err.println("LSS: Resuming accept on " + servsock);
129: si.events |= Selectable.ACCEPT_READY;
130: listen_selsource.update(si);
131: }
132:
133: protected void close() {
134: if (nbservsock == null)
135: return; // If already closed
136: listen_selsource.deregister(si);
137: listen_selsource = null;
138: try {
139: nbservsock.close();
140: } catch (IOException e) {
141: // Ignore
142: }
143: nbservsock = null;
144: ATcpServerSocketClosedEvent closed = new ATcpServerSocketClosedEvent(
145: servsock);
146: compQ.enqueue_lossy(closed);
147: }
148:
149: protected void complete(ATcpConnection conn) {
150: if (DEBUG)
151: System.err.println("LSS: complete called on conn " + conn);
152: if (!compQ.enqueue_lossy(conn)) {
153: if (DEBUG)
154: System.err
155: .println("LSS: Could not enqueue_lossy new conn "
156: + conn);
157: }
158: }
159:
160: public int getLocalPort() {
161: return nbservsock.getLocalPort();
162: }
163:
164: }
|