Mercurial > urweb
comparison lib/js/urweb.js @ 728:2197f0e24a9f
Avoid thread death via message receive
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Thu, 16 Apr 2009 13:00:40 -0400 |
parents | 6fc633d990e7 |
children | 7c6b6c3c7b79 |
comparison
equal
deleted
inserted
replaced
727:ba4c230b7231 | 728:2197f0e24a9f |
---|---|
71 var cl = newClosure(tr.closure); | 71 var cl = newClosure(tr.closure); |
72 cls.v = cons(cl, cls.v); | 72 cls.v = cons(cl, cls.v); |
73 return "cr(" + cl + ")"; | 73 return "cr(" + cl + ")"; |
74 } else | 74 } else |
75 return tr; | 75 return tr; |
76 } | |
77 | |
78 function flattenLocal(s) { | |
79 var cls = {v : null}; | |
80 var r = flatten(cls, s); | |
81 for (cl = cls.v; cl != null; cl = cl.next) | |
82 freeClosure(cl.data); | |
83 return r; | |
76 } | 84 } |
77 | 85 |
78 | 86 |
79 | 87 |
80 // Dynamic tree management | 88 // Dynamic tree management |
257 } | 265 } |
258 | 266 |
259 function er(s) { | 267 function er(s) { |
260 for (var ls = errorHandlers; ls; ls = ls.next) | 268 for (var ls = errorHandlers; ls; ls = ls.next) |
261 ls.data(s)(null); | 269 ls.data(s)(null); |
262 throw s; | 270 throw {uw_error: s}; |
271 } | |
272 | |
273 var failHandlers = null; | |
274 | |
275 function onFail(f) { | |
276 failHandlers = cons(f, failHandlers); | |
277 } | |
278 | |
279 function doExn(v) { | |
280 if (v == null || v.uw_error == null) { | |
281 var s = (v == null ? "null" : v.toString()); | |
282 for (var ls = failHandlers; ls; ls = ls.next) | |
283 ls.data(s)(null); | |
284 } | |
263 } | 285 } |
264 | 286 |
265 | 287 |
266 // Remote calls | 288 // Remote calls |
267 | 289 |
297 | 319 |
298 xhr.send(null); | 320 xhr.send(null); |
299 } | 321 } |
300 | 322 |
301 function rc(uri, parse, k) { | 323 function rc(uri, parse, k) { |
302 var cls = {v : null}; | 324 uri = flattenLocal(uri); |
303 uri = flatten(cls, uri); | |
304 for (cl = cls.v; cl != null; cl = cl.next) | |
305 freeClosure(cl.data); | |
306 | |
307 var xhr = getXHR(); | 325 var xhr = getXHR(); |
308 | 326 |
309 xhr.onreadystatechange = function() { | 327 xhr.onreadystatechange = function() { |
310 if (xhr.readyState == 4) { | 328 if (xhr.readyState == 4) { |
311 var isok = false; | 329 var isok = false; |
408 | 426 |
409 var listener = dequeue(ch.listeners); | 427 var listener = dequeue(ch.listeners); |
410 if (listener == null) { | 428 if (listener == null) { |
411 enqueue(ch.msgs, msg); | 429 enqueue(ch.msgs, msg); |
412 } else { | 430 } else { |
413 listener(msg); | 431 try { |
432 listener(msg); | |
433 } catch (v) { | |
434 doExn(v); | |
435 } | |
414 } | 436 } |
415 } | 437 } |
416 | 438 |
417 connect(); | 439 connect(); |
418 } | 440 } |
449 | 471 |
450 var msg = dequeue(ch.msgs); | 472 var msg = dequeue(ch.msgs); |
451 if (msg == null) { | 473 if (msg == null) { |
452 enqueue(ch.listeners, function(msg) { k(parse(msg))(null); }); | 474 enqueue(ch.listeners, function(msg) { k(parse(msg))(null); }); |
453 } else { | 475 } else { |
454 k(parse(msg))(null); | 476 try { |
477 k(parse(msg))(null); | |
478 } catch (v) { | |
479 doExn(v); | |
480 } | |
455 } | 481 } |
456 } | 482 } |
457 | 483 |
458 | 484 |
459 // App-specific code | 485 // App-specific code |