Chakracore: Is it possible to pause and resume script execution in JSRT?

Created on 19 Feb 2017  Â·  3Comments  Â·  Source: chakra-core/ChakraCore

Hi,

I’m trying to use the built in JSRT engine to build a simple non-visual browser for crawling and data scraping solution. I’m following HTML5 WHATWG specifications.

One point that I don’t know whether it is possible in JSRT or not is the ability to pause the execution of a script, execute another one and then resume the paused script. This is one of the requirements defined in HTML5 specs as described here https://html.spec.whatwg.org/multipage/scripting.html#script-processing-model

In some situations, HTML5 requires to ”Immediately execute the script block, even if other scripts are already executing.” This is defined as “an operation that is to run immediately must interrupt the currently running task, run itself, and then resume the previously running task”

This point is important especially when handling dynamically created and inserted scripts into the DOM. Otherwise, the script engine may block the HTML parser.

I’m aware about JsDisableRuntimeExecution API but this as I know will cancel the execution on the whole runtime, and there is no way to resume the execution again. Also, this is not suitable as I may have multiple execution contexts (for example when dealing with Iframes and other types of nested browsing contexts).

Any idea how to achieve pause and resume behavior in JSRT. Or any workarounds?

Regards,
Atef

Question

Most helpful comment

Others may answer this better. I will try to approach to this problem generally.

Lets consider a JavaScript loop logic below;

for(var i=0; i<100; i++) {
  // do something
}

This will keep the thread busy until the loop ends. In order to pause this at any given time, we may have to pause the execution from another thread.

AFAIK, There is no magical solution to this.

1 - Decide on order prior to running any script. I know, there are cases make this really hard.

2 - You could inject a function call as given below and decide whether you want to pause or not.

void myPauseFunction (....)
{
    if (shouldPause) {
       // call pthread - Windows thread wait / sync etc. to keep this thread on hold
    }
}
for(var i=0; i<100; i++) {
  myPauseFunction();
  // do something
}

3 - One another option is to suspend / resume the thread using C/C++ etc. features..

On Windows you could use SuspendThread and ResumeThread on JS engine's thread. However, this may lead to an unknown behavior due to GC thread / locks, reaching JSRT from another thread etc.. You might have to keep runtime from using background threads. (JsRuntimeAttributeDisableBackgroundWork)

See also pthread_suspend for non Windows.

FYI; regardless from the implementation, suspending the thread is not instant or guaranteed.

P.S. This is not a good option in case you want to run another script while the JS thread is suspended unexpectedly.

4 ) Listen to memory allocation callback -> [JsMemoryAllocationCallback] (https://github.com/Microsoft/ChakraCore/wiki/JsMemoryAllocationCallback) This is similar to (2) and you can keep the execution on pause. However, loading another script here is a bit more tricky (if it is doable properly at all)

All 3 comments

Others may answer this better. I will try to approach to this problem generally.

Lets consider a JavaScript loop logic below;

for(var i=0; i<100; i++) {
  // do something
}

This will keep the thread busy until the loop ends. In order to pause this at any given time, we may have to pause the execution from another thread.

AFAIK, There is no magical solution to this.

1 - Decide on order prior to running any script. I know, there are cases make this really hard.

2 - You could inject a function call as given below and decide whether you want to pause or not.

void myPauseFunction (....)
{
    if (shouldPause) {
       // call pthread - Windows thread wait / sync etc. to keep this thread on hold
    }
}
for(var i=0; i<100; i++) {
  myPauseFunction();
  // do something
}

3 - One another option is to suspend / resume the thread using C/C++ etc. features..

On Windows you could use SuspendThread and ResumeThread on JS engine's thread. However, this may lead to an unknown behavior due to GC thread / locks, reaching JSRT from another thread etc.. You might have to keep runtime from using background threads. (JsRuntimeAttributeDisableBackgroundWork)

See also pthread_suspend for non Windows.

FYI; regardless from the implementation, suspending the thread is not instant or guaranteed.

P.S. This is not a good option in case you want to run another script while the JS thread is suspended unexpectedly.

4 ) Listen to memory allocation callback -> [JsMemoryAllocationCallback] (https://github.com/Microsoft/ChakraCore/wiki/JsMemoryAllocationCallback) This is similar to (2) and you can keep the execution on pause. However, loading another script here is a bit more tricky (if it is doable properly at all)

AFAIK there's no direct way to pause & resume in JSRT. Pausing in the middle of an execution actually leaves the engine in a weird intermediate state and in most cases we don't allow script re-entrancy as it could mess up our internal state.

Looks like this question is answered. Closing.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

gustavopinto picture gustavopinto  Â·  3Comments

jdalton picture jdalton  Â·  4Comments

Kureev picture Kureev  Â·  5Comments

stefanpenner picture stefanpenner  Â·  5Comments

basdl picture basdl  Â·  3Comments