Making Jurassic ThreadSafe

Sep 10, 2011 at 10:08 PM

I'm really interested in making Jurassic thread-safe in the same way most GUI-programming is made thread-safe. In other words, what I would like to do is to make sure that no variables are changed and no function-calls made from outside of the thread the ScriptEngine was spawned on. I think this can be done pretty easily by storing a reference to the thread from the constructor of the ScriptEngine, and then always check that code is run on that thread. Another, and better option (I think), would be to have ScriptEngine spawn a thread it controls, and run all js-code on that thread. That way the ScriptEngine could easily implement things like dispatching and implementing stuff like setTimeout and setInterval in js would be simple too. All js-engines that runs in browser already do this enforcing, which makes using jurassic hard sometimes, because if you want to implement something async you need to be really careful when calling callback-functions and stuff like that.

Another option is global locks, that would make code run on several threads, but only one at a time. I think if it's implemented into property-setters and function-calls that jurassic would be thread-safe.

Coordinator
Sep 11, 2011 at 5:43 AM

> always check that code is run on that thread.

Completely possible, but would require a buttload of checks (one for each publically exposed method).

> spawn a thread it controls, and run all js-code on that thread

Also possible, but the overhead in marshalling calls to and from the worker thread would be substantial.

> All js-engines already do this enforcing

They really don't: the browser JS engines don't have any thread safety.  They just have an inner event loop that works the same as the windows event loop.  Something like this:

while (true) {
  Event e = WaitForNextEvent()
  ProcessEvent(e)
}

Where events can be a mouse click handler or a setInterval handler.

I'm curious as to what the use case for this is.  If I knew what you were trying to achieve maybe I could suggest something more concrete.

Sep 11, 2011 at 5:51 AM

Well, basically I'm writing a irc bot. It runs a lot of stuff asynchronous, so I've implemented an eventloop, the problem is that in all the .NET code I need to have a reference to the eventloop-handler to enforce that all the callbacks are run on the right thread.

--
/Alxandr - mobile

Coordinator
Sep 11, 2011 at 10:47 AM

This may or may not help you, but did you know you can run JS code concurrently by using multiple ScriptEngines?  Just create one ScriptEngine per thread.  Of course this doesn't work if you need to share state - in that case you have no choice but to queue the callbacks and run them one at a time.  Note also that you can call Jurassic methods from different threads - as long as there are no concurrent calls to the same ScriptEngine (or objects created by the ScriptEngine).  Therefore instead of building a queue you can just use a simple lock around the Jurassic Execute method (or whatever calls you use).

To be honest I'm not likely to make any changes in this area because I'm not convinced there is a good answer to this problem.  Supporting full concurrency complicates the code greatly and hampers performance, while still requiring that javascript code be written in a thread-safe manner.  And anything less than full concurrency doesn't buy you much while still having most of the downsides.

Sep 25, 2011 at 7:48 PM

I agree. I've implemented a Queue, and just need to remember to enqueue everything instead of just running it.