Semaphore javascript / test-and-set / lock?

Is there such a thing as an atomic test suite, semaphore, or lock in Javascript?

I have javascript calling async background processes via my own protocol (the background process literally starts in a separate process that is not connected to the browser). I believe that I am faced with a racing condition; the background process returns between my test and my set, twisting things on the javascript side. I need a test operation to make it a real semaphore.

Here is the javascript code that tries to detect background processes and queue them:

Call = function () { var isRunning = true, queue = []; return { // myPublicProperty: "something", call: function (method) { if (isRunning) { console.log("Busy, pushing " + method); queue.push(method); } else { isRunning = true; objccall(method); } }, done: function() { isRunning = false; if (queue.length > 0) { Call.call(queue.shift()); } } }; }(); 

A call is a singleton that implements a sequence; anyone who wants to call an external process calls Call.call ("something").

Any ideas?

+43
javascript concurrency semaphore
Feb 17 '09 at 0:51
source share
6 answers

JavaScript does not have locking semantics, since JS is not a multi-threaded language. Several threads can only work in completely different contexts - for example. HTML5 workflows or things like multiple instances of the JavaScriptCore API context object (I believe SpiderMonkey has a similar concept). They cannot have a shared state, so essentially all of the execution is atomic.

Well, since you have provided some of your code now, I assume that you have something similar to:

 External Process: <JSObject>.isRunning = true; doSomething() <JSObject>.done() 

Or some of them (using the appropriate APIs). In this case, I would expect the JS engine to block if the JS is executed in the context of your js object (which JavaScriptCore will do), otherwise you will probably need to set a manual lock around js execution.

What engine do you use to do all this? I ask because, based on your description, it looks like you are setting a flag from a secondary stream from a language other than JS using the C / C ++ API provided by this language, and most JS modules assume that any manipulation states created using the API will occur in a single thread, usually in the same thread as all execution.

+18
Feb 17 '09 at 1:19
source share

A quick google search for "javascript mutex" returned this article (Implementing mutual exclusion in JavaScript).

+10
Feb 17 '09 at 1:28
source share

Perhaps you could implement a basic integer semaphore, just add the variable to the DOM and lock / unlock it and make sure your functions keep checking it, otherwise timeout =)

If you use a framework like Mootools, you can try to process the application stream with events like onComplete, etc.

+2
Feb 17 '09 at 1:16
source share

I have ajax stuff that populates select lists, I need it to be locked, so I did something like this. I think you could make it simpler, although use deferred and pipes or something else.

 var semaphore=[]; function myFunc(arg){ var dfd; $.when(semaphore[table]).done( function(){ dfd=myFuncInner(arg); } ); return dfd; } function myFuncInner(table){ semaphore[arg] = new $.Deferred(); ... somethingasynchronous({ semaphore[arg].resolve(); }); return semaphore[arg]; } 
0
Jun 08 '14 at 22:33
source share

First of all, although it is true that javaScript is single-threaded, it is NOT true that no serialization mechanism is ever required by a javaScript application.

A simple example is that the submit button should disappear within a set period of time during which an Ajax request to the server is executed. When the asynchronous Ajax request is completed successfully, then a message should appear in which the button was.

Although it would be nice to be able to undo the fadeout button and just set your style to "display: none" once the Ajax request is complete, this is not possible in jQuery. In addition, the solution can use events to synchronize two simultaneous actions, but this is essentially redundant for a simple problem.

The low-tech solution is polling the lock, and when the fadeout completes, it unlocks, but the β€œserver done” message is NOT displayed until the success callback specified by the $ .post parameter is executed.

 var gl_lock; var gl_selfID; function poll_lock(message) { if (gl_lock === 0) { $('#output').text(message).fadeIn(200); window.clearInterval(gl_selfID); } } // end of poll_lock function worker() { // no one gets in or out gl_lock = 1; $.post(..., data,function() { gl_selfID = window.setInterval(poll_lock, 40, data.message); }, "json"); // end of fadeout unlock the semaphore $('#submit-button').fadeOut(400, function() { gl_lock = 0; }); } // end of worker 

Finally, I think this is a more detailed answer, as perrohunter suggested earlier in this discussion.

0
04 Oct '15 at 0:24
source share

I'm not quite sure that the question is asked just like that, but look here at my semaphore object: https://github.com/agamemnus/semaphore.js .

0
Jan 15 '17 at 2:31 on
source share



All Articles