aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Braun <martin.braun@ettus.com>2017-08-01 13:35:58 -0700
committerMoritz Fischer <moritz.fischer@ettus.com>2017-08-07 16:09:50 -0700
commit6667aa071ecfac7418b49354b25c06a40ff4acfe (patch)
tree8af5b53891b3d815dfcfd139b389dabc002ef3ba
parentb5e43a27ab444f9276e15086871a1c249ba3df2b (diff)
downloaduhd-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.h3
-rw-r--r--host/lib/error_c.cpp8
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;