Search code examples
v8

TerminateExecution, IsExecutionTerminating, and Clearing V8 Interrupts


the context

The plv8 javascript language extension for the postgreSQL database uses V8 isolates for computing javascript code as queries. When plv8-based queries are cancelled, a signal-handling code executes the TerminateExecution method of the isolate. This ultimately raises an interrupt, setting the thread-local interrupt_flags for termination. Presumably, when the isolate resumes execution, the interrupt handler will throw a termination exception. Later, the language extension uses the IsExecutionTerminating method to determine if the isolate has received the exception and clears it with CancelTerminateExecution.

the problem

However, in some cases, the call to TerminateExecution was the last interaction with the isolate, before executing a new javascript query. In this case the isolate is still interrupted, but IsExecutionTerminating will return false because that only checks for the exception, not the interrupt. Then, when it begins executing the next query, the interrupt is handled and the exception is thrown and the current query fails because of the cancellation of the previous query.

the question

My question for v8 experts is this: is there any way to effectively clear the interrupts prior to running any js in the isolate? Alternatively, is there any simple way to trigger the exception being thrown so that it can be cancelled prior to any of the query-based code?


Solution

  • Have you tried calling CancelTerminateExecution unconditionally? That should do the trick.

    (If you want, you can also track on your end whether TerminateExecution has been called before, but I think CancelTerminateExecution is so cheap that that isn't even worth it.)