1
2 package org.xwt;
3
4 import java.util.*;
5 import org.xwt.util.*;
6
7
17 public class MessageQueue extends Thread {
18
19
20 private static Message refreshMessage = new Message() { public void perform() { } };
21
22
23 public static void refresh() { add(refreshMessage); }
24
25
26 public static volatile boolean working = false;
27
28 private MessageQueue() { start(); }
29
30
31 private static Queue events = new Queue(50);
32
33
34 public static volatile int nonThreadEventsInQueue = 0;
35
36
37 static Message currentlyPerforming = null;
38
39 private static MessageQueue singleton = new MessageQueue();
40 private static MessageQueueWatcher watcher = new MessageQueueWatcher();
41
42
43 Object lastfunc = null;
44 Message lastmessage = null;
45
46
54 public void run() {
55 Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
56 while(true) {
57 try {
58 int size = events.size();
59 for(int i=0; i<Math.max(1, size); i++) {
60 Message e = (Message)events.remove();
61
62
63
64 if (!(e instanceof Thread)) nonThreadEventsInQueue--;
65 else if (nonThreadEventsInQueue > 0) {
66 add(e);
67 i--;
68 continue;
69 }
70 if (!(e instanceof Thread)) working = true;
71 currentlyPerforming = e;
72
73
74 lastmessage = e;
75 if (e != null && e instanceof ThreadMessage) lastfunc = ((ThreadMessage)e).f;
76
77 e.perform();
78 currentlyPerforming = null;
79 working = false;
80 }
81 working = true;
82 for(int i=0; i<Surface.allSurfaces.size(); i++)
83 ((Surface)Surface.allSurfaces.elementAt(i)).render();
84 working = false;
85
86 } catch (Throwable t) {
87 if (Log.on) Log.log(this, "caught throwable in MessageQueue.run(); this should never happen");
88 if (Log.on) Log.log(this, " currentlyPerforming == " + currentlyPerforming);
89 if (Log.on) Log.log(this, " working == " + working);
90
91
92 if (Log.on) Log.log(this, " lastmessage == " + lastmessage);
93 if (Log.on) Log.log(this, t);
94 if (Log.on) Log.log(this, "resuming MessageQueue loop");
95 }
96 }
97 }
98
99
100 public static void add(Message e) {
101
102
103
104
105
106
107 events.append(e);
108 if (!(e instanceof Thread)) nonThreadEventsInQueue++;
109 }
110
111
112 private static class MessageQueueWatcher extends Thread {
113 long t = System.currentTimeMillis();
114 Message m = null;
115 public MessageQueueWatcher() { start(); }
116 public void run() {
117 while(true) {
118 if ((m != null && m == MessageQueue.currentlyPerforming) || MessageQueue.working) {
119 String what, where;
120 if (m != null && m instanceof ThreadMessage) {
121 where = org.xwt.js.JS.Thread.fromJavaThread((ThreadMessage)m).getSourceName();
122 what = "background thread";
123 } else if (m != null) {
124 where = org.xwt.js.JS.Thread.fromJavaThread(MessageQueue.singleton).getSourceName();
125 what = "event trap";
126 } else {
127 where = org.xwt.js.JS.Thread.fromJavaThread(MessageQueue.singleton).getSourceName();
128 what = "script";
129 }
130 long howlong = (System.currentTimeMillis() - t) / 1000;
131 if (howlong >= 5)
132 if (Log.on) Log.log(this, "note: executing same " + what + " for " + howlong + "s" + " at " + where);
133 } else {
134 m = MessageQueue.currentlyPerforming;
135 t = System.currentTimeMillis();
136 }
137 try { Thread.sleep(1000); } catch (Exception e) { }
138 }
139 }
140 }
141
142 }
143
144
145
146