<div class="gmail_quote">On Fri, Oct 2, 2009 at 9:43 PM, Jonas Sicking <span dir="ltr"><jonas@sicking.cc></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div class="gmail_quote"><div><div></div><div class="h5"><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204, 204, 204);padding-left:1ex"><div class="gmail_quote"><div><div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204, 204, 204);padding-left:1ex">
<div class="gmail_quote">
<div><div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204, 204, 204);padding-left:1ex"><div class="gmail_quote"><div><div>
<blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204, 204, 204);padding-left:1ex">
<div><div>
>> >> > Moreover, there are other examples which have been discussed on the<br>
>> >> > list. There are some DOM operations that can result in a frame<br>
>> >> > receiving<br>
>> >> > a DOM event synchronously. That can result in a nesting of storage<br>
>> >> > locks,<br>
>> >> > which can force us to have to implicitly unlock the outermost lock to<br>
>> >> > avoid<br>
>> >> > deadlocks. Again, the programmer will have very poor visibility into<br>
>> >> > when<br>
>> >> > these things can happen.<br>
>> >><br>
>> >> So far I don't think it has been shown that these events need to be<br>
>> >> synchronous. They all appear to be asynchronous in gecko, and in the<br>
>> >> case of different-origin frames, I'm not even sure there's a way for<br>
>> >> pages to detect if the event was fired asynchronously or not.<br>
>> ><br>
>> > IE and WebKit dispatch some of them synchronously. It's hard to say<br>
>> > which<br>
>> > is correct or if it causes any web compat isues. I'm also not sure that<br>
>> > we<br>
>> > have covered all of the cases.<br>
>><br>
>> It still seems to me that it's extremely unlikely that pages depend on<br>
>> cross origin events to fire synchronously. I can't even think of a way<br>
>> to test if a browser dispatches these events synchronously or not. Can<br>
>> you?<br>
><br>
> i agree that it seems uncommon. maybe there could be some odd app that<br>
> does something after resizing an iframe that could be dependent on the<br>
> event handler setting some data field. this kind of thing is probably even<br>
> less common in the cross-origin case.<br>
<br>
</div></div>But how would you read that data field in the cross-origin frame? I<br>
think it might be possible, but extremely hard.<br>
<div><div></div><div><br></div></div></blockquote><div><br></div></div></div><div>Yeah.</div><div><br></div><div>My concern is simply that I cannot prove that I don't have to worry about this</div><div>problem. Future web APIs might also inadvertently make matters worse.</div>
</div></blockquote></div></div><div><br>I agree it's not ideal, but at the same time I don't think that not allowing synchronous cross-origin APIs is a huge burden. You campaigned heavily against that when we were designing postMessage for wholly other reasons. I would imagine those reasons will hole true no matter what.<br>
</div></div></blockquote><div><br></div></div></div><div>Agreed. That's a good point. In that case, I was concerned about stack depth. The same issue might apply here. Hmm...</div></div></blockquote></div></div><div>
<br>As far as I can see it does.<br>
<br> </div><div><div></div><div class="h5"><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204, 204, 204);padding-left:1ex"><div class="gmail_quote"><div></div><div><br></div><div>
...snip...</div><div><div>
</div><div>
<blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204, 204, 204);padding-left:1ex"><div class="gmail_quote"><div><div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204, 204, 204);padding-left:1ex">
<div class="gmail_quote"><div><div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204, 204, 204);padding-left:1ex"><div><div><br>
>> >> Not quite sure I follow your proposal. How would you for example<br>
>> >> increase the value of a property by one without risking race<br>
>> >> conditions? Or keep two values in different properties in sync? I.e.<br>
>> >> so that if you update one always update the other, so that they never<br>
>> >> have different values.<br>
>> >><br>
>> >> / Jonas<br>
>> ><br>
>> ><br>
>> > Easy. Just like with database, the transaction is the storage lock.<br>
>> > Any<br>
>> > storage<br>
>> > operation performed on that transaction are done atomically. However,<br>
>> > all<br>
>> > storage<br>
>> > operations are asynchronous. You basically string together asynchronous<br>
>> > storage<br>
>> > operations by using the same transaction for each.<br>
>> > We could add methods to get/set multiple items at once to simplify life<br>
>> > for<br>
>> > the coder.<br>
>><br>
>> I think I still don't understand your proposal, could you give some<br>
>> code examples?<br>
>><br>
><br>
><br>
> ripping off database:<br>
> interface ValueStorage {<br>
> void transaction(in DOMString namespace, in<br>
> ValueStorageTransactionCallback callback);<br>
> };<br>
> interface ValueStorageTransactionCallback {<br>
> void handleEvent(in ValueStorageTransaction transaction);<br>
> };<br>
> interface ValueStorageTransaction {<br>
> void readValue(in DOMString name, in ValueStorageReadCallback callback);<br>
> void writeValue(in DOMString name, in DOMString value);<br>
> };<br>
> interface ValueStorageReadCallback {<br>
> void handleEvent(in ValueStorageTransaction transaction, in DOMString<br>
> value);<br>
> };<br>
> then, to use these interfaces, you could implement thread-safe increment:<br>
> window.localStorage.transaction("slice", function(transaction) {<br>
> transaction.readValue("foo", function(transaction, fooValue) {<br>
> transaction.writeValue("foo", ++fooValue);<br>
> })<br>
> })<br>
> to fetch multiple values, you could do this:<br>
> var values = [];<br>
> var numValues = 10;<br>
> function readNextValue(transaction) {<br>
> if (values.length == numValues)<br>
> return; // done!<br>
> var index = values.length;<br>
> transaction.readValue("value" + index, function(transaction, value) {<br>
> values.push(value);<br>
> readNextValue(transaction);<br>
> })<br>
> }<br>
> window.localStorage.transaction("slice", readNextValue);<br>
> This has the property that all IO is non-blocking and the "lock" is held<br>
> only<br>
> for a very limited scope. The programmer is however free to extend the<br>
> life of the lock as needed.<br>
<br>
</div></div>What do you mean by that the "lock" is held for only a very limited<br>
scope? You still want to prevent modifications for as long as the<br>
transaction is being used right? I.e. no modifications can happen<br>
between the read and the write in the first example, and between the<br>
different reads in the second.<br></blockquote><div><br></div></div></div><div>Yes. I only meant that the programmer doesn't have to call a special</div><div>function to close the transaction. It closes by virtue of the last handleEvent</div>
<div>call referring to the transaction returning.</div></div></blockquote></div></div><div><br>So wouldn't you implement this transaction using a lock? To prevent other pages from accessing the localStorage?<br><br></div>
</div></blockquote><div><br></div></div></div><div>Yes, but it wouldn't need to be a normal mutex if that's what you mean. You could just defer callbacks until the transaction completes. It is purely asynchronous locking.</div>
</div></blockquote></div></div><div><br>So how is that then different from from using a Storage API, but only letting you get a reference to the Storage object using a asynchronous API? And of course not allowing the Storage object to be stored in a variable and used outside the callback.<br>
<br></div></div></blockquote><div><br></div><div>The difference is that storage IO is fully asynchronous in the API I proposed. It doesn't have to block the calling thread for reads. I think that is important.</div>
<div><br></div><div>We should never design any APIs that involve synchronous IO (filesystem or network) from the main UI thread.</div><div><br></div><div>-Darin</div></div>