[whatwg] localStorage + worker processes

Jonas Sicking jonas at sicking.cc
Sat Mar 21 13:51:44 PDT 2009


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


More information about the whatwg mailing list