aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Rossetto <aaron.rossetto@ni.com>2021-08-30 12:12:30 -0500
committerAaron Rossetto <aaron.rossetto@ni.com>2021-08-31 07:32:41 -0500
commitf8d8c23e701b5e1bc2c18d1a0f28b7a2699afbac (patch)
treecbbb8cf82a0064a6d2ddfa349f3737e2453ba2ff
parent919043f305efdd29fbdf586e9cde95d9507150e8 (diff)
downloaduhd-f8d8c23e701b5e1bc2c18d1a0f28b7a2699afbac.tar.gz
uhd-f8d8c23e701b5e1bc2c18d1a0f28b7a2699afbac.tar.bz2
uhd-f8d8c23e701b5e1bc2c18d1a0f28b7a2699afbac.zip
uhd: transport: Avoid exceptions in disconnect_receiver()
inline_io_service::disconnect_receiver() uses the recv_link_if parameter as a key into the _recv_tbl map. In some error cases, notably when an underlying link timeout occurs when setting up a transport, that key may not exist in the table. Attempting to index the table by that non-existent key causes an std::out_of_range exception to be thrown. However, in the aforementioned error case, disconnect_receiver() is called as part of a destructor of an object that is in one of the stack frames being unwound as the timeout exception is in flight. Throwing an exception while one is in flight ultimately causes the C++ runtime to terminate the process. (Generally, throwing an exception in a destructor, unless caught within the destructor, is considered a bad practice for this very reason.) This PR modifies disconnect_receiver() to check for the existence of the entry in the map and bypass the access if it is not present, thus preventing the exception from being thrown in this function which is invoked from another object's destructor.
-rw-r--r--host/lib/transport/inline_io_service.cpp20
1 files changed, 10 insertions, 10 deletions
diff --git a/host/lib/transport/inline_io_service.cpp b/host/lib/transport/inline_io_service.cpp
index 7eb3072b7..631ee1bc3 100644
--- a/host/lib/transport/inline_io_service.cpp
+++ b/host/lib/transport/inline_io_service.cpp
@@ -444,17 +444,17 @@ void inline_io_service::connect_receiver(
void inline_io_service::disconnect_receiver(recv_link_if* link, inline_recv_cb* cb)
{
- inline_recv_mux* mux;
- inline_recv_cb* rcvr;
- std::tie(mux, rcvr) = _recv_tbl.at(link);
- if (mux) {
- mux->disconnect(cb);
- if (mux->is_empty()) {
- delete mux;
- mux = nullptr;
+ inline_recv_mux* mux = nullptr;
+ inline_recv_cb* rcvr = nullptr;
+ if (_recv_tbl.count(link)) {
+ std::tie(mux, rcvr) = _recv_tbl.at(link);
+ if (mux) {
+ mux->disconnect(cb);
+ if (mux->is_empty()) {
+ delete mux;
+ mux = nullptr;
+ }
}
- } else {
- rcvr = nullptr;
}
_recv_tbl[link] = std::make_tuple(mux, rcvr);
}