Asynchronicity

Brendan Eich brendan at mozilla.org
Tue Sep 5 14:39:27 PDT 2006


On Sep 5, 2006, at 2:20 PM, P T Withington wrote:

> On 2006-09-05, at 16:58 EDT, Dave Herman wrote:
>
>>> Does the evaluation model give any guidance on atomicity?  That is,
>>
>> I agree that there ought to be atomicity guarantees. Programmers  
>> should be able to assume, for example, that two enqueued functions  
>> or two event handlers won't run concurrently. I *think* that's  
>> current systems use a single event queue (at least for a suitably  
>> sandboxed context, such as a single web page), but I'm not sure.
>
> That would make for a simple model.  There is a certain amount of  
> asynchronous execution though:  event handlers can start firing  
> before the web page is fully rendered.  I don't know if the  
> language spec. can say anything about that, but it fooled me into  
> thinking events were asynchronous.

This is an unstandardized part of the web, yet all browsers must  
match one another to interoperate, at least on content that has  
enough usage for browser vendors to (have to) care.

I intentionally made JS and the original "DOM" (it didn't have a TLA  
in 1995) single-threaded, run-to-completion.  This was and is the  
best fit for most JS hackers and browser implementations.  It means  
no two scripts loaded, or event handlers fired, in any number of  
connected windows, can preempt each other, or nest in each other.   
Yes, that means that this testcase shows a bug in Firefox and all  
Mozilla-based browsers:

<html>
     <head>
         <script>
         var t, i = 0;
         function start() {
             t = document.getElementById('t');
             setInterval(function () {t.value = ++i}, 1000);
         }
         </script>
     </head>
     <body onload="start()">
         <input id="t" value="    ">
         <button onclick="prompt('foo')">foo</button>
     </body>
</html>

While the modal dialog is flying, the interval handler should not run.

>>> since the most popular use of the language is in browsers, which  
>>> are  (asynchronous) event driven, should their be a guarantee  
>>> that  functions run to completion?  Or a mechanism for aborting  
>>> a  function?  Or a
>>
>> I doubt that there will be any asynchronous primitives in the  
>> language any time soon.

Not in the core language.  I've threatened bloody outcomes if anyone  
tries adding threads and monitors (however sugared) in several public  
talks this year.  It's more likely we'll look hard at things like  
STM.  But *after* ES4/JS2 is done, not before.

There is hope that via the WHATWG or the W3C (thanks to WHATWG  
pressure, in my opinion), some of this in-part-11-year-old de-facto  
standard will be specified by a de-jure standard.

>> However there do exist API's for doing things like aborting  
>> enqueued events, e.g.:
>>
>>     http://developer.mozilla.org/en/docs/DOM:window.clearTimeout
>>     http://developer.mozilla.org/en/docs/DOM:window.clearInterval
>>
>> These are relatively benign operations when you have guarantees  
>> that no two pieces of user code will be concurrently executed.  
>> (Other than the question of whether or not the event will be  
>> cancelled before being handled, of course.)

That's inherently racy by design.

>>> mechanism for synchronizing events?  Does the  evaluation model  
>>> at least require that reads and writes of variables  are atomic?
>>
>> By synchronization, do you mean programmer-controlled atomicity  
>> (like Java's `synchronized' construct, for want of a better  
>> example), or do you mean something more like event scheduling?
>
> If there is an atomicity guarantee at the event level (that events  
> run serially), then I don't need anything.

The original Netscape 2 event model guaranteed this, and I believe up  
through Netscape 4 and IE4, browsers kept this promise about events,  
including loaded script executions, running serially.

At some point, things like W3C DOM mutation events came along.  What  
happens when you mutate the DOM from a mutation event handler?  Does  
the second event nest, or defer until the first unwinds?  The spec is  
mute.  Ian Hickson has been testing all browsers in excruciating  
detail, writing down results and trying to codify sane rules, for  
WHATWG specs.  The variation in execution models, and in non- 
determinism, is breathtaking.

Another example that's more relevant than mutation events:  
XMLHttpRequest.  What is its execution model?  Does it preserve run- 
to-completion?  Surprisingly, given the amount of Ajax content that  
does interoperate, the answer in detail varies among popular browsers.

>   On the other hand, if, for instance, an interval event could  
> interrupt or suspend another (long-running) event, it would be nice  
> to have some synchronization primitive to build on.
>
> My experiments indicate that current browsers do serialize events.   
> An interval event is delayed by a long-running event handler.

But not, in Firefox, by a modal dialog.  A gray area at best, or more  
likely our bug.  Your comments in private mail, or here if the list  
members won't be bored, are welcome.

Parting shot: ECMA TG1 is not going to address execution model much  
normatively in ES4 any more than in ES1-3, which only imply that  
there is one thread of execution (along with explicit words about  
"the global object" in ES1-3, which we will fix in ES4 to talk about  
multiple globals and multiple compilation units).  The bulk of the de- 
facto standard and non-standard behavior makes any de-jure standard  
the job of the W3C or successors.  The core language under ECMA TG's  
stewardship does not want or need conventional Java-esque threads and  
monitors.

/be



More information about the Es4-discuss mailing list