shutdown: synchronize station-device teardown#1035
Conversation
Replace the close-time queued Rig/Rotator/CWKeyer shutdown plus fixed sleep with synchronous shutdown paths on each owning worker thread. MainWindow now disconnects station-device singleton signals before teardown and shuts down CWKeyer, Rotator, then Rig before the worker threads are joined. Harden rigctld process cleanup by making RigctldManager::stop() safe to call more than once and by avoiding late cross-thread process shutdown from destructors. Also avoid deleting worker QThread objects if they fail to stop within the bounded join timeout. This fixes an intermittent Windows close crash observed with rigctld sharing active: qlog.exe!RigctldManager::stop() Line 149 qlog.exe!Rig::~Rig() Line 763 The crash occurred while QProcess::waitForFinished() was running during application teardown. Validation: RigctldManagerTest passed, 19 passed / 0 failed / 0 skipped.
|
Thanks for the PR. I only made a small change: the shutdown still runs on the worker thread, but it now uses a queued shutdown request with a timeout guard, so the application will not wait forever if a device does not respond while closing. The overall principle of your patch remains the same. I also kept the regular CW keyer close path using deferred deletion, so normal reconnect/error handling should keep the previous behavior. Could you please test it and confirm whether it still works correctly on your setup? Branch |
|
Thank you very much for all your hard work on QLog. I can see why adding a timeout here is useful, thanks for that. There is an edge case I’m worried about in regard to what happens after that timeout fires. At that point, the main thread no longer knows whether the shutdown work is still queued, already running, or finished. Teardown keeps going anyway, so If you prefer the top-level timeout version, I think the queued callback should handle the timeout case explicitly. I pushed a version close to your branch into the PR with a few changes:
The cancellation flag does not make cleanup complete, and it cannot stop I like the I defer to your judgment, thanks so much. I built and ran it locally on Windows, all tests pass, have not experienced a crash. |
Summary
This fixes an intermittent crash I saw when closing QLog on Windows with rigctld
sharing enabled. The crash was in
RigctldManager::stop(), called fromRig::~Rig(), whileQProcess::waitForFinished()was running.The old shutdown path queued Rig, Rotator, and CWKeyer cleanup to their worker
threads, then slept for a fixed amount of time before the rest of QLog shut down.
That could leave device cleanup racing Qt/application teardown.
This change makes shutdown explicit:
app.exec()returnsRigctldManager::stop()safe to call more than onceQThreadif shutdown times outValidation
RigctldManagerTest: PASSEDNotes
I tested the Rig/rigctld path locally. I do not have Rotator or CWKeyer hardware,
so those paths follow the same shutdown pattern but have not been tested with
real hardware.