lib: Fix lost wakeup in msg_task startup

msg_task_impl's constructor waits on _start_cv until _running is set,
checking the predicate under _mutex. task_loop() set _running and
called notify_one() without taking _mutex, so a notification sent
after the constructor had checked the predicate but before it started
to wait was lost, and the constructor then blocked forever.

The condition-variable handshake replaced a boost::barrier, which
cannot lose a wakeup, in 3855516f6f ("lib: Remove boost::thread usage
from USB transports"), so UHD 4.10.0.0 and 4.11.0.0 are affected. On
a B210 the hang leaves b200_impl's constructor blocked in
msg_task::make() right after "Operating over USB 3.". It shows up
most when the device is opened at a real-time priority, as SDR
applications that raise their priority before opening the device do.

Set _running while holding _mutex, then notify.
This commit is contained in:
Roman Pope 2026-09-23 19:47:00 -04:00 committed by Martin Braun
parent 7a44637627
commit ec86cd7b2c

View File

@ -124,7 +124,12 @@ public:
private:
void task_loop(const task_fcn_type& task_fcn)
{
_running = true;
{
// Set the predicate under the mutex: the constructor checks it under
// _mutex before waiting, so a notify sent in between would be lost.
std::lock_guard<std::mutex> lock(_mutex);
_running = true;
}
_start_cv.notify_one();
try {