diff options
author | Martin Braun <martin.braun@ettus.com> | 2017-08-01 13:35:58 -0700 |
---|---|---|
committer | Moritz Fischer <moritz.fischer@ettus.com> | 2017-08-07 16:09:50 -0700 |
commit | 6667aa071ecfac7418b49354b25c06a40ff4acfe (patch) | |
tree | 8af5b53891b3d815dfcfd139b389dabc002ef3ba | |
parent | b5e43a27ab444f9276e15086871a1c249ba3df2b (diff) | |
download | uhd-6667aa071ecfac7418b49354b25c06a40ff4acfe.tar.gz uhd-6667aa071ecfac7418b49354b25c06a40ff4acfe.tar.bz2 uhd-6667aa071ecfac7418b49354b25c06a40ff4acfe.zip |
C API: Make uhd_get_last_error() thread-safe
The function was directly accessing the error message cache, bypassing
locks, and thus could be faulty if being called the same time as another
UHD component would update the error string.
-rw-r--r-- | host/include/uhd/error.h | 3 | ||||
-rw-r--r-- | host/lib/error_c.cpp | 8 |
2 files changed, 8 insertions, 3 deletions
diff --git a/host/include/uhd/error.h b/host/include/uhd/error.h index 77216dc72..5be04b7b4 100644 --- a/host/include/uhd/error.h +++ b/host/include/uhd/error.h @@ -87,7 +87,8 @@ typedef enum { UHD_API uhd_error error_from_uhd_exception(const uhd::exception* e); -UHD_API const std::string& get_c_global_error_string(); +//! Return a copy of the last error string. +UHD_API std::string get_c_global_error_string(); UHD_API void set_c_global_error_string(const std::string &msg); diff --git a/host/lib/error_c.cpp b/host/lib/error_c.cpp index 3ce63a81d..622d3ee34 100644 --- a/host/lib/error_c.cpp +++ b/host/lib/error_c.cpp @@ -45,11 +45,14 @@ uhd_error error_from_uhd_exception(const uhd::exception* e){ } // Store the error string in a single place in library +// Note: Don't call _c_global_error_string() directly, it needs to be locked +// for thread-safety. Use set_c_global_error_string() and +// get_c_global_error_string() instead. UHD_SINGLETON_FCN(std::string, _c_global_error_string) static boost::mutex _error_c_mutex; -const std::string& get_c_global_error_string(){ +std::string get_c_global_error_string(){ boost::mutex::scoped_lock lock(_error_c_mutex); return _c_global_error_string(); } @@ -66,8 +69,9 @@ uhd_error uhd_get_last_error( size_t strbuffer_len ){ try{ + auto error_str = get_c_global_error_string(); memset(error_out, '\0', strbuffer_len); - strncpy(error_out, _c_global_error_string().c_str(), strbuffer_len); + strncpy(error_out, error_str.c_str(), strbuffer_len); } catch(...){ return UHD_ERROR_UNKNOWN; |