Skip to content

runners/calculator: implement thread-safety in QalculateEngine::evaluate

Libqalculate does not seem to support ability to run multiple computations that are controlled or have timeout set beeing run in the same time. After the timeout was introduced in QalculateEngine this led to BUG 470219, which happens when computations are started from multiple threads in the same time that "confuses" libqalculate computation thread which leads to crash in libqalculate code.

To fix that we need to ensure that only one evaluation is running at single moment of time. This is done via QalculateLock class that is like QMutexLocker but for libqalculate. QalculateLock is implemented with two static mutexes. Mutex s_evalLock is used to ensure that only one evaluation is running at single moment. Mutex s_ctrlLock is used to ensure that thread that aborted evaluation will get to start next evaluation.

BUG: 470219

Testing

Due to tricky nature of this commit it is quite hard to test this, some of most reliable ways to crash krunner that i have found are:

  1. start new instance of krunner and quickly enter digits
  2. put = at start of query and ! in end, then quickly enter and remove numbers between = and !

Also because this bug is related to timeouts i have also checked that BUG 468084 remains fixed. The long running requests like 123456789! and request shown in bug result in krunner showing timed out result in 10 seconds as it should.

Merge request reports