| 1 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> |
|---|
| 2 | <html> |
|---|
| 3 | <head> |
|---|
| 4 | <script type="text/javascript"> |
|---|
| 5 | var djConfig = {isDebug: true}; |
|---|
| 6 | </script> |
|---|
| 7 | <script type="text/javascript" src="../../dojo.js"></script> |
|---|
| 8 | <script language="JavaScript" type="text/javascript"> |
|---|
| 9 | dojo.require("dojo.io.*"); |
|---|
| 10 | </script> |
|---|
| 11 | <script> |
|---|
| 12 | |
|---|
| 13 | |
|---|
| 14 | dojo.debugPaint = function(color, msgObj){ |
|---|
| 15 | dojo.debug(msgObj); |
|---|
| 16 | var console = document.getElementById(djConfig.debugContainerId ? |
|---|
| 17 | djConfig.debugContainerId : dojo.hostenv.defaultDebugContainerId); |
|---|
| 18 | if(!console) { console = dojo.body(); } |
|---|
| 19 | console.lastChild.style.backgroundColor = color; |
|---|
| 20 | } |
|---|
| 21 | |
|---|
| 22 | var adc = ["#3399CC","#CCFF00","#FFCC66", "#66FFCC", "#33FFCC", "#FFCC33", "#FFCC99", |
|---|
| 23 | "#FF00FF", "#99FFFF", "#33FFFF", "#FFFF33", "#FFFF00", "#FFFF66"]; |
|---|
| 24 | var sdc = ["","#99FF00","#FF00FF", "#FF00CC","#FF0099", "#FF0066", "#FF0033"]; |
|---|
| 25 | |
|---|
| 26 | var asyncCalls = 0; |
|---|
| 27 | var gtAsyncCalls = 0; |
|---|
| 28 | var syncCalls = 0; |
|---|
| 29 | var gtSyncCalls = 0; |
|---|
| 30 | var inFlightCount = 0; |
|---|
| 31 | var maxInFlight = 0; |
|---|
| 32 | var requestCount = 0; |
|---|
| 33 | var failure = false; |
|---|
| 34 | |
|---|
| 35 | |
|---|
| 36 | var url = location.href; |
|---|
| 37 | var pos = location.href.lastIndexOf("/") || location.href.lastIndexOf("\\"); |
|---|
| 38 | var url = url.substr(pos + 1); |
|---|
| 39 | |
|---|
| 40 | var aSafe = 0; |
|---|
| 41 | function bindAsync(){ |
|---|
| 42 | count(1,1) |
|---|
| 43 | var c = ++aSafe; |
|---|
| 44 | var p = inFlightCount.toString(); |
|---|
| 45 | p = p.charAt(p.length - 1); |
|---|
| 46 | p = adc[p]; |
|---|
| 47 | dojo.debugPaint(p,c+" async start download"); |
|---|
| 48 | return dojo.io.bind({ |
|---|
| 49 | url: url, |
|---|
| 50 | useCache: 1, |
|---|
| 51 | sync: false, |
|---|
| 52 | load: function(type, data){ |
|---|
| 53 | count(0,1); |
|---|
| 54 | dojo.debugPaint(p,c+" async downloaded"); |
|---|
| 55 | if(c<10){ |
|---|
| 56 | bindAsync(); |
|---|
| 57 | init(); |
|---|
| 58 | if(c>5){ |
|---|
| 59 | getTextSync(); |
|---|
| 60 | }else{ |
|---|
| 61 | bindSync(); |
|---|
| 62 | } |
|---|
| 63 | }else{ |
|---|
| 64 | check(); |
|---|
| 65 | } |
|---|
| 66 | }, |
|---|
| 67 | error: function(type, err){ |
|---|
| 68 | dojo.debug("Error getting "+urlFast); |
|---|
| 69 | dojo.debugShallow(err); |
|---|
| 70 | } |
|---|
| 71 | }); |
|---|
| 72 | } |
|---|
| 73 | var timestop = 0; |
|---|
| 74 | |
|---|
| 75 | function bindSync(){ |
|---|
| 76 | var c = count(1,2); |
|---|
| 77 | dojo.debugPaint(sdc[c],c+" sync start download"); |
|---|
| 78 | dojo.io.bind({ |
|---|
| 79 | url: url, |
|---|
| 80 | useCache: false, |
|---|
| 81 | sync: true, |
|---|
| 82 | load: function(type, data){ |
|---|
| 83 | dojo.debugPaint(sdc[c],c+" sync downloaded"); |
|---|
| 84 | if(c!=1){ |
|---|
| 85 | dojo.debugPaint("red","Thread failure, inFlightCount: "+inFlightCount); |
|---|
| 86 | failure = true; |
|---|
| 87 | check();throw "Error not thread safe"; |
|---|
| 88 | } |
|---|
| 89 | count(0,2); |
|---|
| 90 | }, |
|---|
| 91 | error: function(type, err){ |
|---|
| 92 | dojo.debug("Error getting "+urlSlow); |
|---|
| 93 | dojo.debugShallow(err); |
|---|
| 94 | } |
|---|
| 95 | }); |
|---|
| 96 | } |
|---|
| 97 | |
|---|
| 98 | function getTextSync(){ |
|---|
| 99 | var c = count(1,3); |
|---|
| 100 | dojo.debugPaint(sdc[c],c+" getTextSync start download"); |
|---|
| 101 | var response = dojo.hostenv.getText(url); |
|---|
| 102 | if(response){ |
|---|
| 103 | dojo.debugPaint(sdc[c],c+" getTextSync downloaded"); |
|---|
| 104 | if(c!=1){ |
|---|
| 105 | dojo.debugPaint("red","Thread failure, inFlightCount: "+inFlightCount+" maxInFlight: "+maxInFlight); |
|---|
| 106 | failure = true; |
|---|
| 107 | check();throw "Error not thread safe"; |
|---|
| 108 | } |
|---|
| 109 | } |
|---|
| 110 | count(0,3); |
|---|
| 111 | } |
|---|
| 112 | |
|---|
| 113 | var gtAsafe = 0; |
|---|
| 114 | function getTextAsync(){ |
|---|
| 115 | count(1, 4); |
|---|
| 116 | var c = ++gtAsafe; |
|---|
| 117 | var p = inFlightCount.toString(); |
|---|
| 118 | p = p.charAt(p.length - 1); |
|---|
| 119 | p = adc[p]; |
|---|
| 120 | dojo.debugPaint(p,c+" getTextAsync start downLoad"); |
|---|
| 121 | dojo.hostenv.getText(url, function(){ |
|---|
| 122 | count(0, 4); |
|---|
| 123 | dojo.debugPaint(p,c+" getTextAsync downloaded"); |
|---|
| 124 | if(c<10){ |
|---|
| 125 | getTextAsync(); |
|---|
| 126 | init() |
|---|
| 127 | if(c>5){ |
|---|
| 128 | getTextSync(); |
|---|
| 129 | }else{ |
|---|
| 130 | bindSync(); |
|---|
| 131 | } |
|---|
| 132 | }else{ |
|---|
| 133 | check(); |
|---|
| 134 | } |
|---|
| 135 | }); |
|---|
| 136 | } |
|---|
| 137 | |
|---|
| 138 | function count(add, type){ |
|---|
| 139 | if(add){ |
|---|
| 140 | requestCount++; |
|---|
| 141 | inFlightCount++; |
|---|
| 142 | maxInFlight = (maxInFlight<inFlightCount) ? inFlightCount : maxInFlight; |
|---|
| 143 | }else{ |
|---|
| 144 | inFlightCount--; |
|---|
| 145 | } |
|---|
| 146 | switch(type){ |
|---|
| 147 | case 1: |
|---|
| 148 | return (add) ? ++asyncCalls : --asyncCalls ; |
|---|
| 149 | break; |
|---|
| 150 | case 2: |
|---|
| 151 | return (add) ? ++syncCalls : --syncCalls ; |
|---|
| 152 | break; |
|---|
| 153 | case 3: |
|---|
| 154 | return (add) ? ++gtSyncCalls : --gtSyncCalls ; |
|---|
| 155 | break; |
|---|
| 156 | case 4: |
|---|
| 157 | return (add) ? ++gtAsyncCalls : --gtAsyncCalls ; |
|---|
| 158 | break; |
|---|
| 159 | } |
|---|
| 160 | } |
|---|
| 161 | |
|---|
| 162 | function check(){ |
|---|
| 163 | var div = dojo.byId("check"); |
|---|
| 164 | if(!failure){ |
|---|
| 165 | if(inFlightCount == 0){ |
|---|
| 166 | div.style.backgroundColor = "green"; |
|---|
| 167 | div.firstChild.nodeValue = "Test succeded! maximum requests in flight at the same time: "+maxInFlight |
|---|
| 168 | +" in "+requestCount+" requests"; |
|---|
| 169 | }else if(inFlightCount < 0){ |
|---|
| 170 | |
|---|
| 171 | var str = ""; |
|---|
| 172 | if(asyncCalls < 0){ str = "Async dropped a callback"; } |
|---|
| 173 | if(gtAsyncCalls < 0){ str = "getText async gained a callback"; } |
|---|
| 174 | if(syncCalls < 0){ str = "getText sync gained a callback"; } |
|---|
| 175 | if(gtSyncCalls < 0){ str = "getText sync gained a callback";} |
|---|
| 176 | if(!str){ |
|---|
| 177 | str = "inFlightCount below zero, unknown why"; |
|---|
| 178 | } |
|---|
| 179 | failure = str; |
|---|
| 180 | return check(); |
|---|
| 181 | } |
|---|
| 182 | }else{ |
|---|
| 183 | var str = "Thread failure, inFlightCount: "+inFlightCount |
|---|
| 184 | +" maxInFlight: "+maxInFlight +" in "+requestCount+" requests"; |
|---|
| 185 | str = (typeof failure == "string") ? failure : str; |
|---|
| 186 | div.style.backgroundColor = "red"; |
|---|
| 187 | div.firstChild.nodeValue = str; |
|---|
| 188 | } |
|---|
| 189 | } |
|---|
| 190 | |
|---|
| 191 | function init(){ |
|---|
| 192 | bindAsync(); |
|---|
| 193 | bindSync(); |
|---|
| 194 | getTextSync(); |
|---|
| 195 | getTextAsync(); |
|---|
| 196 | |
|---|
| 197 | bindAsync(); |
|---|
| 198 | getTextSync(); |
|---|
| 199 | getTextAsync(); |
|---|
| 200 | bindSync(); |
|---|
| 201 | |
|---|
| 202 | bindAsync(); |
|---|
| 203 | getTextAsync(); |
|---|
| 204 | bindSync(); |
|---|
| 205 | getTextSync(); |
|---|
| 206 | |
|---|
| 207 | |
|---|
| 208 | getTextAsync(); |
|---|
| 209 | bindAsync(); |
|---|
| 210 | getTextSync(); |
|---|
| 211 | bindSync(); |
|---|
| 212 | |
|---|
| 213 | bindAsync(); |
|---|
| 214 | bindSync(); |
|---|
| 215 | getTextSync(); |
|---|
| 216 | getTextAsync(); |
|---|
| 217 | |
|---|
| 218 | bindAsync(); |
|---|
| 219 | getTextSync(); |
|---|
| 220 | getTextAsync(); |
|---|
| 221 | bindSync(); |
|---|
| 222 | |
|---|
| 223 | bindAsync(); |
|---|
| 224 | getTextAsync(); |
|---|
| 225 | bindSync(); |
|---|
| 226 | getTextSync(); |
|---|
| 227 | |
|---|
| 228 | getTextAsync(); |
|---|
| 229 | bindAsync(); |
|---|
| 230 | getTextSync(); |
|---|
| 231 | bindSync(); |
|---|
| 232 | |
|---|
| 233 | bindAsync(); |
|---|
| 234 | bindSync(); |
|---|
| 235 | getTextSync(); |
|---|
| 236 | getTextAsync(); |
|---|
| 237 | |
|---|
| 238 | getTextAsync(); |
|---|
| 239 | bindAsync(); |
|---|
| 240 | } |
|---|
| 241 | |
|---|
| 242 | dojo.addOnLoad(init); |
|---|
| 243 | </script> |
|---|
| 244 | </head> |
|---|
| 245 | <body> |
|---|
| 246 | <h2>Check thread safety in XmlHttpRequest, mostly important in Khtml</h2> |
|---|
| 247 | <h3>Test relates to both dojo.io.bind and dojo.hostenv.getText as it is the combination of these that is causing the browser hang.</h3> |
|---|
| 248 | <pre> |
|---|
| 249 | Propose of this test is to test for thread safety in XHR |
|---|
| 250 | The problem is if you start 2 async requests, and the content of one |
|---|
| 251 | these start a sync request, this sync request can be interupted |
|---|
| 252 | by the other async request. That hangs the browser indefinetly. |
|---|
| 253 | It should wait with the async callback until the sync exits |
|---|
| 254 | </pre> |
|---|
| 255 | <div id="check" style="background-color: yellow; text-align:center; font-size: 2em;">Probing... please wait!</div><br/><br/> |
|---|
| 256 | </body> |
|---|
| 257 | </html> |
|---|