Skip to content

Commit

Permalink
Block TrikScriptRunnerWorker thread when reading values from sensors
Browse files Browse the repository at this point in the history
  • Loading branch information
MinyazevR authored and iakov committed Nov 13, 2024
1 parent 77c0e58 commit 21296bb
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,18 @@ void TrikLineSensorAdapter::detect()

QVector<int> TrikLineSensorAdapter::read()
{
QMetaObject::invokeMethod(mLineSensor, "read");
/* Sensor values are calculated by timer in the UI Thread
* (subscription in plugins/robots/interpreters/trikKitInterpreterCommon/src/TrikBrick)
* and are also forced through TrikScriptRunner when calculating sensor values (except for Gyroscope::read).
* This heavily loads the UI thread, and in incorrect code like
* while (true) { brick.lineSensor("video1").read(); }
* the UI thread gets blocked by sensor reading tasks, making the user interface non-functional.
* As a hot-fix, it is proposed to calculate values using Qt::BlockingQueuedConnection,
* which will force waiting for the sensor value calculation instead of queuing new tasks
* in the UI thread every few milliseconds (this is critical for reading from sensors
* whose handlers take a relatively long time, as the queue contains many reading tasks
* while returning old (already calculated) sensor values, which forces new tasks to be queued). */
QMetaObject::invokeMethod(mLineSensor, "read", Qt::BlockingQueuedConnection);
return mLineSensor->lastData(); // hopefully the same format
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,18 @@ TrikSensorEmu::TrikSensorEmu(kitBase::robotModel::robotParts::ScalarSensor *sens
int TrikSensorEmu::read()
{
//mSensor->read(); test crash fixes
QMetaObject::invokeMethod(mSensor, "read");

/* Sensor values are calculated by timer in the UI Thread
* (subscription in plugins/robots/interpreters/trikKitInterpreterCommon/src/TrikBrick)
* and are also forced through TrikScriptRunner when calculating sensor values (except for Gyroscope::read).
* This heavily loads the UI thread, and in incorrect code like
* while (true) { brick.sensor("A1").read() }
* the UI thread gets blocked by sensor reading tasks, making the user interface non-functional.
* As a hot-fix, it is proposed to calculate values using Qt::BlockingQueuedConnection,
* which will force waiting for the sensor value calculation instead of queuing new tasks
* in the UI thread every few milliseconds (this is critical for reading from sensors
* whose handlers take a relatively long time, as the queue contains many reading tasks
* while returning old (already calculated) sensor values, which forces new tasks to be queued). */
QMetaObject::invokeMethod(mSensor, "read", Qt::BlockingQueuedConnection);
return mSensor->lastData(); // not best, race conditions?
}

0 comments on commit 21296bb

Please sign in to comment.