From d67bd603e9062a187bd1a33f6e2d3a6d9d8a6517 Mon Sep 17 00:00:00 2001 From: Tom Tsou Date: Thu, 15 Jun 2017 15:35:02 -0700 Subject: transceiver: Fix POWEROFF crash on USRP2/N200/X300 devices Upon issuing POWEROFF command to a running transceiver, UHD interfacing thread state may become undefined if the device is stopped with I/O threads still active. Bad behavior is device dependent with only network based USRP devices affected. USB based device thread behavior stops and shutdowns as expected. Tested with N200, X300, and B210. Tested solutions include the following: 1. Set pthread_setcanceltype() with PTHREAD_CANCEL_ASYNCHRONOUS 2. Add sleep delay to allow I/O threads to timeout before stopping the device 3. Wait for I/O threads to join after cancellation before stopping the device This patch resolves the issue by with the third approach. Number 1 is not guaranteed to always work with UHD internals as driver code may explicitly set thread parameters. Using sleep calls to fix order-of-operation issues is almost never a good idea. Change-Id: Ib72ab98a27a02084b040319046c92d1c4157ae4c --- Transceiver52M/Transceiver.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Transceiver52M/Transceiver.cpp b/Transceiver52M/Transceiver.cpp index 66eff7f..61da416 100644 --- a/Transceiver52M/Transceiver.cpp +++ b/Transceiver52M/Transceiver.cpp @@ -297,6 +297,10 @@ void Transceiver::stop() LOG(NOTICE) << "Stopping the transceiver"; mTxLowerLoopThread->cancel(); mRxLowerLoopThread->cancel(); + mTxLowerLoopThread->join(); + mRxLowerLoopThread->join(); + delete mTxLowerLoopThread; + delete mRxLowerLoopThread; for (size_t i = 0; i < mChans; i++) { mRxServiceLoopThreads[i]->cancel(); @@ -315,11 +319,6 @@ void Transceiver::stop() mTxPriorityQueues[i].clear(); } - mTxLowerLoopThread->join(); - mRxLowerLoopThread->join(); - delete mTxLowerLoopThread; - delete mRxLowerLoopThread; - mOn = false; LOG(NOTICE) << "Transceiver stopped"; } -- cgit v1.2.3