mobile/hackery: try to prevent QLM race condition

Apparently in some cases there is a race condition where the action to
delete a dive is still running while a corresponding QML object (but not
that action itself) is being deleted, likely because the action is
becoming invisible once the dive is actually deleted. I'm speculating
that this may be somewhere inside the delegates for the repeater showing
the actions in the context drawer.

This commit is a bit of a convoluted hack. We create a property to hold
the dive id to be deleted and then call a function to delete that dive
via a timer. This of course creates a blatant race condition in itself -
but the user is extremely unlikely to be able to use the context menu to
delete two different dives within 100ms. The code tries to keep that
race window as small as possible.

There has got to be a better way to do this.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
Dirk Hohndel 2021-01-18 13:34:43 -08:00
parent 29060feaa8
commit 31a979371e

View file

@ -278,11 +278,40 @@ Kirigami.ScrollablePage {
visible: currentItem && currentItem.myData && !currentItem.myData.isTrip
onTriggered: manager.toggleDiveInvalid(currentItem.myData.id)
}
Timer {
// this waits a tenth of a second and then deletes the dive -
// this way the Action in the contextDrawer can complete its signal handler before
// having the visual QML element going away and being deleted (which could cause a crash)
id: delayedDelete
interval: 100
onTriggered: {
var myDiveToDelete = diveToDelete // try to minimize the window for a race
diveToDelete = -1
if (myDiveToDelete !== -1) {
manager.appendTextToLog("now deleting dive id " + myDiveToDelete)
manager.deleteDive(myDiveToDelete)
} else {
manager.appendTextToLog("delayedDelete triggered with dive id -1");
}
}
}
property int diveToDelete: -1
property QtObject deleteAction: Kirigami.Action {
text: qsTr("Delete dive")
icon { name: ":/icons/trash-empty.svg" }
visible: currentItem && currentItem.myData && !currentItem.myData.isTrip
onTriggered: manager.deleteDive(currentItem.myData.id)
onTriggered: {
if (diveToDelete === -1) {
diveToDelete = currentItem.myData.id
manager.appendTextToLog("setting timer to delete dive " + diveToDelete)
delayedDelete.start()
contextDrawer.close()
manager.appendTextToLog("closed drawer, done with the action")
} else {
manager.appendTextToLog("deleteAction triggered with diveToDelete already set to " +
diveToDelete + " -- ignoring just to be safe");
}
}
}
property QtObject mapAction: Kirigami.Action {
text: qsTr("Show on map")