Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I safety modify a global variable from within indexedDB callbacks?

I am kicking off a bunch of indexeddb actions and want them to be able to increment a counter (and change some other things as well, but for this question, just assume it's incrementing a counter) when they complete. I know from the IndexedDB specs that it runs the callbacks in different threads (although, despite that wording, I'm not sure if implementations have to use threads or not). But AFAIK, JavaScript/HTML5 has nothing that guarantees thread safety of something, so I'm afraid of the following situation:

/* Sequence involved in incrementing a variable "behind the scenes" */
//First callback calls i++; (it's 0 at this point)
load r0,[i]  ; load memory into reg 0

//Second callback calls i++ (it's still 0 at this point)
load r1,[i]  ; load memory into reg 1

//First callback's sequence continues and increments the temporary spot to 1
incr r0      ; increment reg 0

//Second callback's sequence continues and also increments the temporary spot to 1
incr r1      ; increment reg 1

//First callback sequence finishes, i === 1
stor [i],r0  ; store reg 0 back to memory


//Second callback sequence finishes, i === 1
stor [i],r1  ; store reg 1 back to memory

(Or something along those lines)

So what are my options? Could I spawn web workers in each of the callbacks that call postMessage and the listener increments it? Something like:

increment.js (Our Worker's code)

//Our count
var count = 0;

 function onmessage(event)
 {
    count += event.data;
 }

main.js

//Our "thread-safe" worker?
var incrementer = new Worker( "increment.js" );

//Success handler (has diff thread)
req.onsuccess = function(event) {  

    ...finish doing some work...

    //Increment it
    incrementer.postmessage( 1 );
};

Would that work? Or would the web worker's onmessage still occur in the callback's thread? Is there any way to make it be in the global thread?

like image 361
Don Rhummy Avatar asked Jun 15 '13 06:06

Don Rhummy


1 Answers

The only mention of the word 'thread' in the referenced documentation is that IndexedDB API methods don't block the calling thread (that still doesn't imply that the methods are run in separate threads, though, it merely states that the methods are asynchronous in nature), but no mention whatsoever that callbacks will be run in different threads at all.

Also, JavaScript by itself is single-threaded, so you can safely assume that the callbacks will all be run in the same ('global') thread, and will be called sequentially, not concurrently.

So there's not need for Web workers, you can just increment the global variable directly from the callbacks themselves:

req.onsuccess = function(event) {  
  count += event.data;
};
like image 69
robertklep Avatar answered Oct 31 '22 17:10

robertklep