1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package zeus.actors.rtn;
25
26 import java.util.*;
27
28
29 import zeus.util.*;
30 import zeus.concepts.*;
31 import zeus.actors.*;
32 import zeus.actors.event.*;
33 import zeus.actors.graphs.*;
34 import zeus.actors.rtn.util.*;
35
36 class NodeWaitTable extends Hashtable implements Runnable {
37 protected zeus.util.Queue queue = null;
38 protected Engine engine;
39 protected Vector dont_add_list = new Vector();
40 protected long sleep_until = Long.MAX_VALUE;
41
42 public NodeWaitTable(Engine engine, Queue queue) {
43 this.engine = engine;
44 this.queue = queue;
45 }
46
47
48 public void run() {
49 Thread.currentThread().setName ("NodeWaitTable");
50 for(;;) {
51 try {
52 Core.DEBUG(3,"Before Wakeup\n" + this);
53 wakeup();
54 long duration = sleep_period();
55 Core.DEBUG(3,engine.getAgentContext().whoami() +
56 " sleeping for " + duration);
57 Core.DEBUG(3,"After Wakeup\n" + this);
58 synchronized(this) {
59 wait(duration);
60 }
61 }
62 catch(InterruptedException e) {
63 }
64 }
65 }
66
67 protected synchronized long sleep_period() {
68 long timeout = Long.MAX_VALUE;
69 Node node;
70 Vector list;
71 double t;
72
73
74 if ( !this.isEmpty() ) {
75 t = Double.MAX_VALUE;
76 Enumeration enum = this.elements();
77 while( enum.hasMoreElements() ) {
78 list = (Vector)enum.nextElement();
79 for(int i = 0; i < list.size(); i++ ) {
80 node = (Node)list.elementAt(i);
81 t = Math.min(t,node.getTimeout());
82 }
83 }
84 t = t - engine.getAgentContext().now();
85 timeout = (long)(t*engine.getAgentContext().getClockStep());
86 }
87 timeout = Math.max(timeout,0);
88
89 sleep_until = (timeout == Long.MAX_VALUE) ? timeout :
90 System.currentTimeMillis() + timeout;
91 return timeout;
92 }
93
94 public synchronized void wakeup() {
95 Node node;
96 Vector list;
97 String key;
98
99 double now = engine.getAgentContext().now();
100 Core.DEBUG (4,"wakeup>> now == " + String.valueOf(now) );
101
102
103 Enumeration enum = this.keys();
104 while( enum.hasMoreElements() ) {
105 Core.DEBUG(4, "in while - keys >= !");
106 key = (String)enum.nextElement();
107 list = (Vector)this.get(key);
108 for(int i = 0; i < list.size(); i++ ) {
109 node = (Node)list.elementAt(i);
110 Core.DEBUG (4,"Timeout == " + node.getTimeout());
111 if ( now >= node.getTimeout() ) {
112 queue.enqueue(node);
113 list.removeElementAt(i);
114 }
115 }
116 if ( list.isEmpty() )
117 this.remove(key);
118 }
119 notifyAll();
120 }
121
122 public synchronized void wakeup(String key) {
123 Node node;
124 Vector list;
125
126 list = (Vector)this.remove(key);
127
128 if ( list == null ) {
129
130
131
132
133 dont_add_list.addElement(key);
134 return;
135 }
136
137 for(int i = 0; i < list.size(); i++ ) {
138 node = (Node)list.elementAt(i);
139 queue.enqueue(node);
140 }
141 list = null;
142 notify();
143 }
144
145 public synchronized void add(Node node) {
146 String key = node.getMsgWaitKey();
147 Core.DEBUG(3,"Adding wait_node: " + node.getDescription() + "[" + key + "]");
148
149
150 if ( dont_add_list.contains(key) ) {
151 dont_add_list.removeElement(key);
152 queue.enqueue(node);
153 return;
154 }
155
156 Vector list = (Vector)this.get(key);
157 if ( list == null ) {
158 list = new Vector();
159 this.put(key,list);
160 }
161 list.addElement(node);
162
163 double t = node.getTimeout();
164 t = t - engine.getAgentContext().now();
165 long duration = (long)(t*engine.getAgentContext().getClockStep());
166 if ( System.currentTimeMillis() + duration < sleep_until ) {
167 Core.DEBUG(3,"Will notify... ");
168 notify();
169 }
170 else
171 Core.DEBUG(3,"No notify: sleeping for " + (sleep_until - System.currentTimeMillis()));
172
173 }
174
175 public String toString() {
176 double now = engine.getAgentContext().now();
177 String out = "NodeWaitTable: now = " + Misc.decimalPlaces(now,4) + "\n";
178
179 synchronized(this) {
180 Enumeration enum = this.keys();
181 Vector List;
182 Node node;
183 String key;
184 while( enum.hasMoreElements() ) {
185 key = (String)enum.nextElement();
186 List = (Vector)this.get(key);
187 out += "\t" + key + "\n";
188 for(int i = 0; i < List.size(); i++) {
189 node = (Node)List.elementAt(i);
190 out += "\t\t" + node +
191 "\t" + Misc.decimalPlaces(node.getTimeout(),4) + "\n";
192 }
193 }
194 }
195 return out;
196 }
197 }