001: /*
002:
003: Derby - Class org.apache.derbyTesting.functionTests.harness.ProcessStreamResult
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to You under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derbyTesting.functionTests.harness;
023:
024: import java.io.*;
025: import java.sql.Timestamp;
026:
027: public class ProcessStreamResult implements Runnable {
028:
029: protected InputStream in;
030: protected OutputStreamWriter outStream;
031: // Encoding to be used to read output of test jvm process
032: protected String encoding;
033:
034: /**
035: * Flag to find out if the work was finished
036: * successfully without being interrupted
037: * in between because of a timeout setting
038: */
039: protected boolean finished;
040: protected IOException ioe;
041: protected Thread myThread;
042: protected long startTime;
043:
044: /**
045: * Flag to keep state of whether the myThread has timed out.
046: * When interrupted is true, the myThread will exit
047: * from its work.
048: */
049: protected boolean interrupted;
050:
051: /**
052: * time in minutes for myThread to timeout in case it
053: * has not finished its work before that.
054: * timeout handling only comes into effect only when Wait()
055: * is called.
056: */
057: protected int timeout;
058:
059: public ProcessStreamResult(InputStream in,
060: BufferedOutputStream bos, String timemin)
061: throws IOException, InterruptedException {
062: this (in, bos, timemin, null, null);
063: }
064:
065: public ProcessStreamResult(InputStream in,
066: BufferedOutputStream bos, String timemin,
067: String inEncoding, String outEncoding) throws IOException,
068: InterruptedException {
069: this .in = in;
070: if (outEncoding == null) {
071: this .outStream = new OutputStreamWriter(bos);
072: } else {
073: this .outStream = new OutputStreamWriter(bos, outEncoding);
074: }
075: this .encoding = inEncoding;
076: this .startTime = System.currentTimeMillis();
077: if (timemin != null) {
078: Integer i = new Integer(timemin);
079: timeout = i.intValue();
080: } else
081: timeout = 0;
082: myThread = new Thread(this );
083: myThread.setPriority(Thread.MIN_PRIORITY);
084: myThread.start();
085: }
086:
087: public void run() {
088: //System.out.println("Thread run... " + tname);
089: if (in == null) {
090: System.out.println("The inputstream is null");
091: System.exit(1);
092: }
093:
094: try {
095: char[] ca = new char[1024];
096: int valid;
097: interrupted = false;
098:
099: // Create an InputStreamReader with encoding, if specified.
100: // Otherwise, use default.
101: InputStreamReader inStream;
102: if (encoding != null)
103: inStream = new InputStreamReader(in, encoding);
104: else
105: inStream = new InputStreamReader(in);
106:
107: // keep reading from the stream as long as we have not
108: // timed out
109: while (((valid = inStream.read(ca, 0, ca.length)) != -1)
110: && !interrupted) {
111: //System.out.println("Still reading thread: " + tname);
112: /* if (timeout > 0) {
113: long millis = System.currentTimeMillis();
114:
115: long diff = millis - startTime;
116:
117: int mins = (int) (diff / (1000 * 60));
118:
119: if (mins > timeout) {
120: System.out.println("Timeout, kill the thread... ");
121: //myThread.dumpStack();
122: synchronized (this)
123: {
124: interrupted = true;
125: finished = true;
126: notifyAll();
127: return;
128: }
129: }
130: }
131: */outStream.write(ca, 0, valid);
132: outStream.flush();
133: }
134: } catch (IOException ioe) {
135: //System.out.println(ioe);
136: //ioe.printStackTrace();
137: }
138:
139: // if we timed out, then just leave
140: if (interrupted)
141: return;
142:
143: synchronized (this ) {
144: // successfully finished the work, notifyAll and leave.
145: finished = true;
146: notifyAll();
147: }
148: }
149:
150: /**
151: * Wait till the myThread has finished its work or incase a timeout was set on this
152: * object, then to set a flag to indicate the myThread to leave at the end of the
153: * timeout period.
154: *
155: * Behavior is as follows:
156: * 1) If timeout is set to a valid value (>0) - in this case, if myThread has not
157: * finished its work by the time this method was called, then it will wait
158: * till the timeout has elapsed or if the myThread has finished its work.
159: *
160: * 2)If timeout is not set ( <= 0) - in this case, if myThread has not
161: * finished its work by the time this method was called, then it will wait
162: * till myThread has finished its work.
163: *
164: * If timeout is set to a valid value, and the timeout amount of time has elapsed,
165: * then the interrupted flag is set to true to indicate that it is time for the
166: * myThread to stop its work and leave.
167: *
168: * @return true if the timeout happened before myThread work was finished
169: * else false
170: * @throws IOException
171: */
172: public boolean Wait() throws IOException {
173: synchronized (this ) {
174: // It is possible that we have finished the work
175: // by the time this method Wait() was called,
176: // so need to check if that is the case, before we
177: // go into a wait.
178: if (finished)
179: return interrupted;
180:
181: if (timeout > 0) {
182: long millis = System.currentTimeMillis();
183:
184: long diff = millis - startTime;
185:
186: int mins = (int) (diff / (1000 * 60));
187:
188: if (mins > timeout) {
189: interrupted = true;
190: return interrupted;
191: }
192: }
193: try {
194: // find timeout in milliseconds
195: long timeoutms = timeout * 60 * 1000L;
196:
197: if (timeout > 0)
198: // wait till notified or till timeoutms has elapsed
199: wait(timeoutms);
200: else
201: wait(); // wait till notified
202:
203: // if myThread didnt finish its work and we reached
204: // here, that means we just timedout.
205: // In that case, indicate that we were interrupted and leave.
206: // myThread will read the value of interrupted and
207: // stop its work and leave.
208: if (!finished)
209: interrupted = true;
210: } catch (InterruptedException ie) {
211: interrupted = true;
212: System.out.println("Interrupted: " + ie.toString());
213: }
214: }
215: return interrupted;
216: }
217: }
|