Reputation: 45685
I evaluate JavaScript in my Qt application using QScriptEngine::evaluate(QString code)
. Let's say I evaluate a buggy piece of JavaScript which loops forever (or takes too long to wait for the result). How can I abort such an execution?
I want to control an evaluation via two buttons Run
and Abort
in a GUI. (But only one execution is allowed at a time.)
I thought of running the script via QtConcurrent::run
, keeping the QFuture
and calling cancel()
when the Abort
is was pressed. But the documentation says that I can't abort such executions. It seems like QFuture
only cancels after the current item in the job has been processed, i.e. when reducing or filtering a collection. But for QtConcurrent::run
this means that I can't use the future to abort its execution.
The other possibility I came up with was using a QThread
and calling quit()
, but there I have a similar problems: It only cancels the thread if / as soon as it is waiting in an event loop. But since my execution is a single function call, this is no option either.
QThread
also has terminate()
, but the documentation makes me worry a bit. Although my code itself doesn't involve mutexes, maybe QScriptEngine::evaluate
does behind the scenes?
Warning: This function is dangerous and its use is discouraged. The thread can be terminated at any point in its code path. Threads can be terminated while modifying data. There is no chance for the thread to clean up after itself, unlock any held mutexes, etc. In short, use this function only if absolutely necessary.
Is there another option I am missing, maybe some asynchronous evaluation feature?
Upvotes: 0
Views: 969
Reputation: 19112
http://doc.qt.io/qt-4.8/qscriptengine.html#details
It has a few sections that address your concerns:
http://doc.qt.io/qt-4.8/qscriptengine.html#long-running-scripts
http://doc.qt.io/qt-4.8/qscriptengine.html#script-exceptions
http://doc.qt.io/qt-4.8/qscriptengine.html#abortEvaluation
http://doc.qt.io/qt-4.8/qscriptengine.html#setProcessEventsInterval
Hope that helps.
Upvotes: 1
Reputation: 45685
While the concurrent task itself can't be aborted "from outside", the QScriptEngine
can be told (of course from another thread, like your GUI thread) to abort the execution:
QScriptEngine::abortEvaluation(const QScriptValue & result = QScriptValue())
The optional parameter is used as the "pseudo result" which is passed to the caller of evaluate()
.
You should either set a flag somewhere or use a special result value in abortEvaluation()
to make it possible for the caller routine to detect that the execution was aborted.
Note: Using isEvaluating()
you can see if an evaluation is currently running.
Upvotes: 0