001: package com.quadcap.net.server;
002:
003: /* Copyright 1999 - 2003 Quadcap Software. All rights reserved.
004: *
005: * This software is distributed under the Quadcap Free Software License.
006: * This software may be used or modified for any purpose, personal or
007: * commercial. Open Source redistributions are permitted. Commercial
008: * redistribution of larger works derived from, or works which bundle
009: * this software requires a "Commercial Redistribution License"; see
010: * http://www.quadcap.com/purchase.
011: *
012: * Redistributions qualify as "Open Source" under one of the following terms:
013: *
014: * Redistributions are made at no charge beyond the reasonable cost of
015: * materials and delivery.
016: *
017: * Redistributions are accompanied by a copy of the Source Code or by an
018: * irrevocable offer to provide a copy of the Source Code for up to three
019: * years at the cost of materials and delivery. Such redistributions
020: * must allow further use, modification, and redistribution of the Source
021: * Code under substantially the same terms as this license.
022: *
023: * Redistributions of source code must retain the copyright notices as they
024: * appear in each source code file, these license terms, and the
025: * disclaimer/limitation of liability set forth as paragraph 6 below.
026: *
027: * Redistributions in binary form must reproduce this Copyright Notice,
028: * these license terms, and the disclaimer/limitation of liability set
029: * forth as paragraph 6 below, in the documentation and/or other materials
030: * provided with the distribution.
031: *
032: * The Software is provided on an "AS IS" basis. No warranty is
033: * provided that the Software is free of defects, or fit for a
034: * particular purpose.
035: *
036: * Limitation of Liability. Quadcap Software shall not be liable
037: * for any damages suffered by the Licensee or any third party resulting
038: * from use of the Software.
039: */
040:
041: import java.io.File;
042: import java.io.FileOutputStream;
043: import java.io.IOException;
044: import java.io.InputStream;
045: import java.io.OutputStream;
046:
047: import java.util.Hashtable;
048:
049: import java.net.InetAddress;
050: import java.net.Socket;
051:
052: import com.quadcap.util.ConfigString;
053: import com.quadcap.util.Debug;
054:
055: /**
056: * A worker is a runnable with a context, in/out streams, and (when active)
057: * a socket.
058: *
059: * @author Stan Bailes
060: */
061: public abstract class Worker implements Runnable {
062: Server server;
063: Object lock = new Object();
064: protected Socket socket = null;
065: int sport = -1;
066: boolean terminate = false;
067:
068: static int wcnt = 0;
069: int cnt = wcnt++;
070:
071: protected Object context;
072: //#ifdef DEBUG
073: protected FileOutputStream log = null;
074: //#endif
075: protected WorkerInputStream win = null;
076: protected WorkerOutputStream wout = null;
077:
078: public String toString() {
079: return "Worker " + cnt;
080: }
081:
082: public void init(Server server, Object context) {
083: this .server = server;
084: this .context = context;
085: }
086:
087: public void init(Server server, Object context, String name)
088: throws IOException {
089: init(server, context);
090: //#ifdef DEBUG
091: this .log = null;
092: int trc = Integer.parseInt(ConfigString.find(
093: "com.quadcap.net.server.trace", "0").toString());
094: if (trc > 0) {
095: try {
096: new File("logs").mkdir();
097: } catch (Throwable t) {
098: }
099: log = new FileOutputStream("logs/" + name + "-" + cnt
100: + ".log");
101: }
102: win = new WorkerInputStream(log);
103: wout = new WorkerOutputStream(log);
104: //#else
105: //- win = new WorkerInputStream(null);
106: //- wout = new WorkerOutputStream(null);
107: //#endif
108: }
109:
110: public int getId() {
111: return cnt;
112: }
113:
114: void handle(Socket socket, int sport) {
115: this .socket = socket;
116: this .sport = sport;
117: synchronized (lock) {
118: lock.notify();
119: }
120: }
121:
122: public void run() {
123: //Jni j = new Jni("work");
124: final WorkerInputStream lwin = win;
125: final WorkerOutputStream lwout = wout;
126: while (!terminate) {
127: //j.reset();
128: boolean interrupted = false;
129: synchronized (lock) {
130: //j.dump("sync");
131: try {
132: if (socket == null)
133: lock.wait();
134: //j.dump("got socket");
135: } catch (InterruptedException e) {
136: }
137: }
138: if (terminate)
139: return;
140: try {
141: //j.dump("in try");
142: lwin.reset(socket.getInputStream());
143: //j.dump("win.reset");
144: lwout.reset(socket.getOutputStream());
145: //j.dump("wout.reset");
146: doSession();
147: //j.dump("doSession");
148:
149: } catch (Throwable t) {
150: Debug.print(t);
151: } finally {
152: try {
153: wout.close();
154: } catch (Throwable t) {
155: }
156: try {
157: socket.close();
158: } catch (Throwable t) {
159: }
160: socket = null;
161: server.returnIdleWorker(this );
162: }
163: }
164: }
165:
166: public final WorkerInputStream getInputStream() {
167: return win;
168: }
169:
170: public final WorkerOutputStream getOutputStream() {
171: return wout;
172: }
173:
174: public final Socket getSocket() {
175: return socket;
176: }
177:
178: public final String getHostName() {
179: return socket.getLocalAddress().getHostName();
180: }
181:
182: public final int getPort() {
183: return sport;
184: }
185:
186: /**
187: * Return the IP address of the agent that sent the request.
188: */
189: public String getRemoteAddr() {
190: InetAddress ia = socket.getInetAddress();
191: return ia.getHostAddress();
192: }
193:
194: public String getRemoteHost() {
195: InetAddress ia = socket.getInetAddress();
196: return ia.getHostName();
197: }
198:
199: public abstract void doSession() throws Exception;
200:
201: public void stop() {
202: terminate = true;
203: try {
204: synchronized (lock) {
205: lock.notifyAll();
206: }
207: } catch (Throwable t) {
208: }
209: }
210: }
|