wren-lang / wren

The Wren Programming Language. Wren is a small, fast, class-based concurrent scripting language.
http://wren.io
MIT License
6.9k stars 552 forks source link

How to abort execution while in a tight\infinite loop? #773

Open debevv opened 4 years ago

debevv commented 4 years ago

Suppose we call wrenInterpret() on this Wren script:

while(true) {}

I tried calling wrenFiberAbort() (from another thread), but looks like it doesn't work.

What's the correct way to interrupt the execution of the VM from C?

mhermier commented 4 years ago

Wren VM is not thread safe, so this not the way to go. Thought you can call a foreign function that returns true or false depending if the loop needs to continue.

debevv commented 4 years ago

Hi, thanks for the fast response. I don't control the code being executed. So I basically wait for a timeout, and If wrenInterpret() still didn't return, I want to kill/abort its execution from the outside. A plus would be a way to detect that the script is stuck in a loop, instead of using a timeout, but I understand that it is beyond the scope of my request.

mhermier commented 4 years ago

Ok so you mean you try to detect/debug infinite loop from external/user provided code? If so there is no such thing right now, but it is pretty easy to change the DISPATCH macro to either to detect that the fiber as an error or to call a debugging callback that can stop the execution at (small execution time cost)

debevv commented 4 years ago

I'll leave the stuck detection for later, for now I would like a way to make the VM check if the current fiber was aborted, and this should work in any situation. Do you think setting a flag from another thread (with wrenAbortFiber() or another C function), and making DISPATCH check for that flag and return WREN_RESULT_RUNTIME_ERROR would work?

EDIT: I think the condition to check in DISPATCH could be simply vm->fiber->error != NULL

mhermier commented 4 years ago

You should only need to call wrenHasError at DISPATCH and return accordingly. (There is a high chance that it works, since I see virtually no possibility that any compiler can be able to inline reading the error value)

You might also need to call STORE_FRAME before returning so the fiber state is valid if you want to display a stack-trace.

Other than that I think you are quite done, thought only test will really gives guarantee.

debevv commented 4 years ago

Ok, thank you. Do you think calling wrenAbortFiber() from a thread separate from wrenInterpret() could cause some concurrency problem, though? What happens, for example, if I call it while a foreign function is also calling it?

mhermier commented 4 years ago

There will be some concurrency creating and defining the error.

So I would suggest that you create a variant of wrenAbort that take an handle, so the error can be created before hand, in a thread safe state.