FreeWRL / FreeX3D 4.3.0
WriterThread.java
1// copyright (c) 1997,1998 stephen f. white
2//
3// This program is free software; you can redistribute it and/or modify
4// it under the terms of the GNU General Public License as published by
5// the Free Software Foundation; either version 2, or (at your option)
6// any later version.
7//
8// This program is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11// GNU General Public License for more details.
12//
13// You should have received a copy of the GNU General Public License
14// along with this program; see the file COPYING. If not, write to
15// the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
16
17package vrml.external.FreeWRLEAI;
18
19import java.io.IOException;
20//JAS import java.io.EOFException;
21//JAS import java.util.Vector;
22//JAS import java.util.Enumeration;
23
24class WriterThread extends Thread {
25 private VFieldOutputStream output;
26 private MessageQueue transientMessages = new MessageQueue();
27 private MessageQueue messages = new MessageQueue();
28 private boolean running;
29 private boolean timerSet;
30 private long timeout;
31 private static final long TIMEOUT = 100;
32 private WriterThreadObserver observer;
33
34 WriterThread(VFieldOutputStream output, WriterThreadObserver observer) {
35 this.output = output;
36 this.observer = observer;
37 }
38
39 public void run()
40 {
41 running = true;
42 while (running) {
43 try {
44 synchronized (this) {
45 if (timerSet) {
46 long t = timeout - System.currentTimeMillis();
47 if (t > 0) wait(t);
48 } else {
49 wait();
50 }
51 if (timerSet && System.currentTimeMillis() > timeout) {
52 // move all messages from transient queue to main queue
53 for(;;) {
54 Message msg = transientMessages.dequeue();
55 if (msg == null) break;
56 messages.enqueue(msg);
57 }
58 timerSet = false;
59 }
60 }
61 // send all queued messages
62
63 // this is outside the synchronized block so that new
64 // messages can come in even if sendMessage() blocks
65 for(;;) {
66 Message msg = messages.dequeue();
67 if (msg == null) break;
68 sendMessage(msg);
69 }
70 } catch (InterruptedException e) {
71 running = false;
72 }
73 }
74 }
75
76 // this is the main access point to this object -- it enqueues
77 // the given message on the appropriate queue, and wakes up the
78 // sleeping thread
79
80 public synchronized void send(Message msg)
81 {
82 if (msg.field < 0) {
83 messages.enqueue(msg);
84 } else if (timerSet) {
85 transientMessages.enqueueUnique(msg);
86 } else {
87 messages.enqueue(msg);
88 timeout = System.currentTimeMillis() + TIMEOUT;
89 timerSet = true;
90 }
91 notify();
92 }
93
94 // secondary access point -- stop the writer thread
95
96 public synchronized void stopThread()
97 {
98 running = false;
99 notify();
100 }
101
102 // sendMessage() actually sends a message (woohoo)
103
104 private void sendMessage(Message message)
105 {
106 try {
107 output.writeInt(message.id);
108 output.writeShort(message.field);
109 output.writeField(message.value);
110 output.flush();
111 } catch (IOException e) {
112 observer.onError(e);
113 }
114 }
115}