jes notes Index Gallery . Shaft passers Snap issues

2025-02-24

Last modified: 2025-02-25 09:21:27

< 2025-02-23 2025-02-25 >

FreeCAD

I'm going to work on making the MainGui register a "task runner" that allows aborting long-running operations, and then App::Docment::recompute() will use the task runner, and we'll get to abort on every full recompute!

And we can potentially use the same thing at other levels.

This is not working. It is giving some errors about timers in the terminal:

QObject::startTimer: Timers cannot be started from another thread
QBasicTimer::start: Timers cannot be started from another thread

And it seems like it's waiting for a second, then showing the dialog, and then doing the really quick operation, so it just delays everything and always pops up.

And when I close a sketch, the dialog comes up and never finishes. So definitely something is wrong.

So I'm going to do it again but from within gdb and try to get a backtrace of the thread that is stuck.

It looks like it is stuck trying to acquire the Python GIL!

So probably the problem is that the GIL is held by another thread, and when we try to do a computation in a new thread it thinks it needs to re-acquire it.

Adding Py_BEGIN_ALLOW_THREADS before starting the thread and Py_END_ALLOW_THREADS after joining it seems to solve it.

I noticed that in one instance the progress dialog stayed up after the operation completed - is this a race between isVisible() and invokeMethod()? isVisible() says the dialog is not visible, then it pops up before our thread exits, but we don't invoke the method because we thought it wasn't visible.

OK, but the Py_BEGIN_ALLOW_THREADS causes a segfault if the main thread doesn't already hold the GIL. Maybe we acquire it explicitly first? Seems to work.

Next up is despite my best efforts we somehow have 2 computation dialogs up at the same time.

Oh! It's because the "task runner" is starting one and some other code is explicitly spawning a ComputationDialog. I just need to make the rest of the code explicitly use the task runner instead.

Working in most places, but I'm getting a segfault when setting an alias in a spreadsheet cell.

I've stashed and am rebuilding with the previous commit to see if I've definitely just introduced this breakage or if it was already there. I also noticed that in the Tasks menu the "Pad", "Pocket" etc. no longer underline or hover, will see if that was already broken before. The segfault is somewhere inside Qt painting text or something, so plausibly related.

The previous version does let me assign aliases to spreadsheet cells, but doesn't highlight "Pad", "Pocket", etc. on hover.

Making it only do the ComputationDialog from the main thread didn't help.

What if it's some sort of race condition to do with trying to update the text on a label after the dialog has been torn down? I will try increasing the timeout from 1 second to 10 seconds and see if it solves it, seems unlikely that setting an alias on a spreadsheet cell would take a second though.

Still segfaults.

What if I just disable ComputationDialog and have it as a straight pass-through? No segfault.

What if I remove all the dialog stuff and just computeThread.join() straight away? Still segfaults.

What if I only do the "force abort" dialog and skip the main dialog? Still segfaults. Duh.

What if ComputationDialog::Show() does nothing? Still segfaults.

What if I remove the GIL stuff? Then it hangs at creating a document.

What if I make the whole function just call func() and return when the GIL is already held? No segfault and no hang! OK, so that's an option.

Can I make it so it passes ownership of the GIL into the thread and then passes it back after? Still segfaults.

OK then, for now I guess we just don't do ComputationDialog if GIL is held.

Car ramp toy

I'm printing the first part, but I noticed it lifted up at the ends, so I'm adding mouse ears to prevent that:

And they'll just need trimming off with a knife.

Also trying out print-by-object for the first time:

Unsure what is going to happen with the "flow dynamics calibration" area, maybe it only does it for the first filament?

< 2025-02-23 2025-02-25 >