diff options
| author | Abdo-Gaber <abdo.gaber@ni.com> | 2019-03-25 15:30:36 +0100 | 
|---|---|---|
| committer | michael-west <michael.west@ettus.com> | 2019-05-21 16:12:07 -0700 | 
| commit | ec69cdf30c1b182338f4bfdefe61470d7113b84e (patch) | |
| tree | 7b140b06069438568cb3a909fd479cf90bd7c153 | |
| parent | cbba2d7b50a2e24b33f6b9ae44e847da06484165 (diff) | |
| download | uhd-ec69cdf30c1b182338f4bfdefe61470d7113b84e.tar.gz uhd-ec69cdf30c1b182338f4bfdefe61470d7113b84e.tar.bz2 uhd-ec69cdf30c1b182338f4bfdefe61470d7113b84e.zip  | |
log: fix deadlock issue on Windows machines
In log.cpp, a deadlock can occur while popping elements from the log
queue. If the queue is empty, the call does not timeout, and waits
infinitely. Replacing pop_with_wait() with pop_with_timed_wait() solves
this issue.
| -rw-r--r-- | host/lib/utils/log.cpp | 35 | 
1 files changed, 32 insertions, 3 deletions
diff --git a/host/lib/utils/log.cpp b/host/lib/utils/log.cpp index 8126d46b7..0d1ab0469 100644 --- a/host/lib/utils/log.cpp +++ b/host/lib/utils/log.cpp @@ -1,6 +1,7 @@  //  // Copyright 2012,2014,2016 Ettus Research LLC  // Copyright 2018 Ettus Research, a National Instruments Company +// Copyright 2019 Ettus Research, a National Instruments Brand  //  // SPDX-License-Identifier: GPL-3.0-or-later  // @@ -20,7 +21,8 @@  #include <memory>  #include <thread> -namespace pt = boost::posix_time; +namespace pt                  = boost::posix_time; +constexpr double READ_TIMEOUT = 0.5; // Waiting time to read from the queue  // Don't make these static const std::string -- we need their lifetime guaranteed!  #define PURPLE "\033[35;1m" // purple @@ -244,6 +246,9 @@ public:      ~log_resource(void){          _exit = true; + +#ifndef BOOST_MSVC // push a final message is required, since the pop_with_wait() function +                   // will be used.          // We push a final message to kick the pop task out of it's wait state.          // This wouldn't be necessary if pop_with_wait() could fail. Should          // that ever get fixed, we can remove this. @@ -257,9 +262,11 @@ public:          );          final_message.message = "";          push(final_message); -#ifndef UHD_LOG_FASTPATH_DISABLE +#    ifndef UHD_LOG_FASTPATH_DISABLE          push_fastpath(""); -#endif +#    endif +#endif // BOOST_MSVC +          _pop_task->join();          {              std::lock_guard<std::mutex> l(_logmap_mutex); @@ -309,8 +316,16 @@ public:          // For the lifetime of this thread, we run the following loop:          while (!_exit) { +#ifdef BOOST_MSVC +            // Some versions of MSVC will hang if threads are being joined after main has +            // completed, so we need to guarantee a timeout here +            if (_log_queue.pop_with_timed_wait(log_info, READ_TIMEOUT)) { +                _handle_log_info(log_info); +            } +#else              _log_queue.pop_with_wait(log_info); // Blocking call              _handle_log_info(log_info); +#endif // BOOST_MSVC          }          // Exit procedure: Clear the queue @@ -326,8 +341,16 @@ public:  #ifndef UHD_LOG_FASTPATH_DISABLE          std::string msg;          while (!_exit) { +#    ifdef BOOST_MSVC +            // Some versions of MSVC will hang if threads are being joined after main has +            // completed, so we need to guarantee a timeout here +            if (_fastpath_queue.pop_with_timed_wait(msg, READ_TIMEOUT)) { +                std::cerr << msg << std::flush; +            } +#    else              _fastpath_queue.pop_with_wait(msg);              std::cerr << msg << std::flush; +#    endif // BOOST_MSVC          }          // Exit procedure: Clear the queue @@ -342,7 +365,13 @@ public:  #ifndef UHD_LOG_FASTPATH_DISABLE          std::string msg;          while (!_exit) { +#    ifdef BOOST_MSVC +            // Some versions of MSVC will hang if threads are being joined after main has +            // completed, so we need to guarantee a timeout here +            _fastpath_queue.pop_with_timed_wait(msg, READ_TIMEOUT); +#    else              _fastpath_queue.pop_with_wait(msg); +#    endif // BOOST_MSVC          }          // Exit procedure: Clear the queue  | 
