1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 package org.apache.commons.httpclient.server;
33
34 import java.io.InputStream;
35 import java.io.OutputStream;
36
37 /***
38 * Pumps data between a pair of input / output streams. Used to
39 * connect the two ends (left and right) of a bidirectional communication channel.
40 * Instances of this class are thread safe.
41 *
42 * @author Ortwin Glueck
43 */
44 class BidiStreamProxy {
45 private StreamProxy leftToRight, rightToLeft;
46 private int state = 0;
47
48 /***
49 * Sets up a new connection between two peers (left and right)
50 * @param leftIn input channel of the left peer
51 * @param leftOut output channel of the left peer
52 * @param rightIn input channel of the right peer
53 * @param rightOut output channel of the right peer
54 */
55 public BidiStreamProxy(InputStream leftIn, OutputStream leftOut, InputStream rightIn, OutputStream rightOut) {
56 leftToRight = new StreamProxy(leftIn, rightOut);
57 rightToLeft = new StreamProxy(rightIn, leftOut);
58 }
59
60 /***
61 * Starts pumping the information from left to right and vice versa.
62 * This is performed asynchronously so this method returns immediately.
63 */
64 public synchronized void start() {
65 if (state != 0) throw new IllegalStateException("Can not start twice");
66 leftToRight.start();
67 rightToLeft.start();
68 state = 1;
69 }
70
71 /***
72 * Aborts the communication between the peers and releases all resources.
73 * Note: The method does not wait for the pump threads to terminate.
74 */
75 public synchronized void abort() {
76 if (leftToRight != null) leftToRight.abort();
77 if (rightToLeft != null) rightToLeft.abort();
78 leftToRight = null;
79 rightToLeft = null;
80 }
81
82 /***
83 * Blocks until all data has been copied. Basically calls the
84 * join method on the pump thread.
85 * @throws InterruptedException
86 */
87 public void block() throws InterruptedException {
88 if (state != 1) throw new IllegalStateException("Can not block before started");
89 leftToRight.block();
90 rightToLeft.block();
91 }
92 }