0

I thought I won't ever need to handle synchronization problems and critical sections in JavaScript because it is single threaded. Well...

Problem

Multiple website sends data to multiple locally hosted pages which accesses the same piece of memory at the same time, causing a race condition.

Here's a simple code that I just wrote that will let two children compute a result and send it back to parent:

window.addEventListener("load", function() {
    //threads analogy in JavaScript!
    if (location.search.length) {
        //receiver
        var query = decodeURIComponent(location.search.slice(1));
        var data = JSON.parse(query).value;

        //handle data.
        //start CRITICAL SECTION
        localStorage.storage = +localStorage.storage + data;
        //end CRITICAL SECTION

        location.href = "about:blank"; //exit
    } else {
        //master
        sum = document.getElementById("sum");
        sum.innerText = localStorage.storage = "0";

        window.addEventListener("storage", function() {
            //data received from receiver
            sum.innerText = localStorage.storage;
        });
    }
});

Multiple pages will calculate a number and send in back to the parent:

var frame = document.createElement("iframe");
frame.src = 'http://localhost:8080/master.html?{"value":1}';    //port 8080
document.body.appendChild(frame);
var n=0;
frame.addEventListener("load", function(){
    if(n) document.body.removeChild(frame);
    else  n=1;
}

Since localStorage is shared between pages of the same domain, and all these pages are running on different threads, this literally causing a race condition, in JavaScript.

I tried creating 2 instances which each of them simultaneously and continuously send back a value of 1 10 times. The result I got at the end is always less than 20.

In C there is mutex to save our lives. How should I approach this problem in JavaScript where there is no locking mechanisms?

This graph might be easier to understand:

Community
  • 1
  • 1
Derek 朕會功夫
  • 92,235
  • 44
  • 185
  • 247
  • iframe's can run code in teh parent frame as long as they are same origin ... use that fact and you wont run into the problem ... I think ... your code makes no sense to me at all – Jaromanda X Dec 05 '15 at 07:43
  • @JaromandaX This whole code is to get around the Same Origin Policy problem with localStorage which does not involve any server code. However by doing this it introduces a critical section. – Derek 朕會功夫 Dec 05 '15 at 07:43
  • are your iframes supposed to be interacting with the parent page? – Jaromanda X Dec 05 '15 at 07:45
  • `which accesses the same piece of memory at the same time` - how do achieve this miraculous cross origin communication to even get a race condition in the first place? – Jaromanda X Dec 05 '15 at 07:46
  • To my knowledge, there is no built-in locking in JavaScript or localStorage. – forgivenson Dec 05 '15 at 07:47
  • @JaromandaX No. The frames are only or sending GET requests to localhost, which will act as receivers and 1. get data from shared memory 2. process data 3. store back data. – Derek 朕會功夫 Dec 05 '15 at 07:47
  • Possible duplicate: [Is locastorage thread-safe](http://stackoverflow.com/questions/22001112/is-localstorage-thread-safe) and a related article: [Javascript concurrency and locking the HTML5 Local Storage](http://balpha.de/2012/03/javascript-concurrency-and-locking-the-html5-localstorage/). – jfriend00 Dec 05 '15 at 07:47
  • @jfriend00 That doesn't seem to answer my question since it never provided a solution... – Derek 朕會功夫 Dec 05 '15 at 07:50
  • @Derek朕會功夫 - the second article referenced does attempt to provide a solution. – jfriend00 Dec 05 '15 at 07:51
  • @Derek朕會功夫 so the race condition is on the **server** – Jaromanda X Dec 05 '15 at 07:51
  • @JaromandaX There is no server code. Everything is running inside a browser. – Derek 朕會功夫 Dec 05 '15 at 07:52
  • @jfriend00 Yea I just reloaded the page and saw your updated comment. Thanks I will take a look at it! – Derek 朕會功夫 Dec 05 '15 at 07:52
  • You could also possibly identify one master window per browser (nominate any window that is open) and communicate with that window via messaging and have ONLY that master window modify the contentious piece of LocalStorage, thus making it atomic since all writes go through one single-threaded window. – jfriend00 Dec 05 '15 at 07:54
  • This might work, but I can't think of a way for them to be communicating with each other. – Derek 朕會功夫 Dec 05 '15 at 07:59
  • look at using [postMessage](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) – Jaromanda X Dec 05 '15 at 08:03
  • @JaromandaX Nice! Thank you! By the way, the `LockableStorage` does not seem to work in my tests. – Derek 朕會功夫 Dec 05 '15 at 08:11

0 Answers0