- From: Jonas Sicking <jonas@sicking.cc>
- Date: Sat, 21 Mar 2009 13:51:44 -0700
On Sat, Mar 21, 2009 at 9:38 AM, Aaron Boodman <aa at google.com> wrote: > On Sat, Mar 21, 2009 at 12:48 AM, Jonas Sicking <jonas at sicking.cc> wrote: >> What we could do, is to have an API like >> >> getLocalStorage(callback); >> >> This function returns immediately, but will then call the callback >> function as soon as the localStorage becomes available and the lock >> been acquired. This would always happen asynchronously off the event >> loop, which means that once the callback returns the lock is released >> again. > > Funny, a few of us from Chromium were discussing a similar solution privately. > > Actually, I don't believe that it is required that the callback run > asynchronously. All the callback is used for is establishing the lock > lifetime explicitly, and we assume that this will usually make the > lock lifetime short. So we can block while we wait for it to become > available. This is just like the behavior today without workers. The problem with synchronously grabbing the lock is that we can only ever have one feature that uses synchronous locks, otherwise we'll risk dead-locks. Say that we make document.cookie behave the same way (to prevent multi-process browsers like IE8 and chrome from having race conditions). So that if you call document.getCookiesWithLock(callback) we'll synchronously grab a lock and call the callback function. This would cause two pages like the ones below to potentially deadlock: Page 1: getLocalStorage(function(storage) { document.getCookiesWithLock(function(cookieContainer) { storage.foo = cookieContainer.getCookie('cookieName'); }); ]); Page 2: document.getCookiesWithLock(function(cookieContainer) { getLocalStorage(function(storage) { cookieContainer.setCookie('cookieName', storage.bar); }); }); The point here isn't to propose a new cookie API, but rather that as soon as we introduce more than one lock that can be synchronously acquired, we run the risk of deadlocks if people don't grab them in the right order. While we could make the implementation detect this and case the second page to throw when a deadlock is detected, that just turns the deadlock into a race condition since pages are unlikely to handle this exception correctly given that it generally doesn't happen. By making all lock acquiring async, we ensure that script can only ever grab one lock at a time, thus preventing people from grabbing multiple locks in different order and causing deadlocks. There is actually another alternative. We could specify an order that locks have to be acquired if you grab more than one. So for example we could say that the order is localStore > cookie > otherRandomFeature In other words, if you want both the localStore and cookie features, you have to grab first localStore and then cookie. Attempting to grab localStore once you have acquired the cookie lock *always* results in an exception being thrown, even if there currently is no deadlock. Anyone specifying a new feature that uses locking would have to define where in the locking order this lock is placed. However this API design does not seem very web developer friendly. / Jonas
Received on Saturday, 21 March 2009 13:51:44 UTC