001: /* tjws - DualSocketAcceptor.java
002: * Copyright (C) 1999-2007 Dmitriy Rogatkin. All rights reserved.
003: * Redistribution and use in source and binary forms, with or without
004: * modification, are permitted provided that the following conditions
005: * are met:
006: * 1. Redistributions of source code must retain the above copyright
007: * notice, this list of conditions and the following disclaimer.
008: * 2. Redistributions in binary form must reproduce the above copyright
009: * notice, this list of conditions and the following disclaimer in the
010: * documentation and/or other materials provided with the distribution.
011: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
012: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
013: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
014: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
015: * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
016: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
017: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
018: * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
019: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
020: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
021: * SUCH DAMAGE.
022: *
023: * Visit http://tjws.sourceforge.net to get the latest infromation
024: * about Rogatkin's products.
025: * $Id: DualSocketAcceptor.java,v 1.2 2007/02/22 23:53:12 rogatkin Exp $
026: * Created on Feb 21, 2007
027: * @author Dmitriy
028: */
029: package rogatkin.web;
030:
031: import java.io.IOException;
032: import java.net.InetAddress;
033: import java.net.ServerSocket;
034: import java.net.Socket;
035: import java.util.Map;
036: import java.util.concurrent.BlockingQueue;
037: import java.util.concurrent.LinkedBlockingQueue;
038: import java.util.concurrent.TimeUnit;
039:
040: import Acme.Serve.SSLAcceptor;
041: import Acme.Serve.Serve;
042:
043: public class DualSocketAcceptor extends SSLAcceptor {
044: protected static class TwoHeadServerSocket extends ServerSocket {
045: protected BlockingQueue<Socket> requestQueue;
046:
047: protected ServerSocket socket1, socket2;
048:
049: private Thread currentThread;
050:
051: public TwoHeadServerSocket(ServerSocket socket1,
052: ServerSocket socket2) throws IOException {
053: requestQueue = new LinkedBlockingQueue<Socket>(1000); // ?? backlog
054: // ArrayBlockingQueue
055: Thread thread;
056: if (socket1 != null) {
057: thread = new Thread(new AcceptQueuer(socket1),
058: "Accept processor 1");
059: thread.setDaemon(true);
060: thread.start();
061: this .socket1 = socket1;
062: }
063: if (socket2 != null) {
064: thread = new Thread(new AcceptQueuer(socket2),
065: "Accept processor 2");
066: thread.setDaemon(true);
067: thread.start();
068: this .socket2 = socket2;
069: }
070: }
071:
072: public Socket accept() throws IOException {
073: Socket result;
074: currentThread = Thread.currentThread();
075: for (;;) {
076: try {
077: result = requestQueue.poll(1000L, TimeUnit.SECONDS);
078: if (result != null)
079: return result;
080: } catch (InterruptedException e) {
081: break;
082: }
083: }
084: throw new IOException();
085: }
086:
087: public void close() throws IOException {
088: if (currentThread != null)
089: currentThread.interrupt();
090: IOException ioe = null;
091: try {
092: socket1.close();
093: } catch (IOException ioe1) {
094: ioe = ioe1;
095: }
096: socket2.close();
097: if (ioe != null)
098: throw ioe;
099: }
100:
101: public String toString() {
102: return "" + socket1 + "/" + socket2;
103: }
104:
105: class AcceptQueuer implements Runnable {
106: ServerSocket socket;
107:
108: AcceptQueuer(ServerSocket socket) {
109: this .socket = socket;
110: }
111:
112: public void run() {
113: for (;;)
114: try {
115: requestQueue.put(socket.accept());
116: } catch (InterruptedException e) {
117: return;
118: } catch (IOException e) {
119: break;
120: }
121: }
122: }
123: }
124:
125: public void init(Map inProperties, Map outProperties)
126: throws IOException {
127: super .init(inProperties, outProperties);
128: int port = inProperties.get(Serve.ARG_PORT) != null ? ((Integer) inProperties
129: .get(Serve.ARG_PORT)).intValue()
130: : Serve.DEF_PORT;
131: int bl = 50;
132: try {
133: // TODO: consider conversion at getting the argument
134: bl = Integer.parseInt((String) inProperties
135: .get(ARG_BACKLOG));
136: if (bl < 2)
137: bl = 2;
138: } catch (Exception e) {
139: }
140: InetAddress ia = null;
141: if (inProperties.get(Serve.ARG_BINDADDRESS) != null)
142: try {
143: ia = InetAddress.getByName((String) inProperties
144: .get(Serve.ARG_BINDADDRESS));
145: } catch (Exception e) {
146: }
147:
148: socket = new TwoHeadServerSocket(
149: new ServerSocket(port, bl, ia), socket);
150: }
151: }
|