From d14fc35e433d4256805c059920bc07569ab07ebc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Blin?= <sebastien.blin@savoirfairelinux.com> Date: Fri, 6 Oct 2023 15:21:53 -0400 Subject: [PATCH] pupnp: fix hanging of UpnpDownloadXmlDoc in PUPnP Sadly, this method is async, and can cause really long delay in shutdown, but at least, avoid to call UPnPFinish before the end of the download (else this method never returns) GitLab: #8 Change-Id: I80df3da9b884b93a331aae738eae9a27be898fe2 --- src/upnp/protocol/pupnp/pupnp.cpp | 12 ++++++++++++ src/upnp/protocol/pupnp/pupnp.h | 6 ++++++ 2 files changed, 18 insertions(+) diff --git a/src/upnp/protocol/pupnp/pupnp.cpp b/src/upnp/protocol/pupnp/pupnp.cpp index 8db0517..d07cc20 100644 --- a/src/upnp/protocol/pupnp/pupnp.cpp +++ b/src/upnp/protocol/pupnp/pupnp.cpp @@ -194,6 +194,9 @@ PUPnP::terminate(std::condition_variable& cv) clientRegistered_ = false; observer_ = nullptr; + std::unique_lock<std::mutex> lk(ongoingOpsMtx_); + destroying_ = true; + cvOngoing_.wait(lk, [&]() { return ongoingOps_ == 0; }); UpnpUnRegisterClient(ctrlptHandle_); @@ -779,6 +782,12 @@ void PUPnP::downLoadIgdDescription(const std::string& locationUrl) { if(logger_) logger_->debug("PUPnP: downLoadIgdDescription {}", locationUrl); + { + std::lock_guard<std::mutex> lk(ongoingOpsMtx_); + if (destroying_) + return; + ongoingOps_++; + } IXML_Document* doc_container_ptr = nullptr; int upnp_err = UpnpDownloadXmlDoc(locationUrl.c_str(), &doc_container_ptr); @@ -794,6 +803,9 @@ PUPnP::downLoadIgdDescription(const std::string& locationUrl) } }); } + std::lock_guard<std::mutex> lk(ongoingOpsMtx_); + ongoingOps_--; + cvOngoing_.notify_one(); } void diff --git a/src/upnp/protocol/pupnp/pupnp.h b/src/upnp/protocol/pupnp/pupnp.h index 4c0ea78..7deb4fb 100644 --- a/src/upnp/protocol/pupnp/pupnp.h +++ b/src/upnp/protocol/pupnp/pupnp.h @@ -243,6 +243,12 @@ private: // Shutdown synchronization bool shutdownComplete_ {false}; + + // Count ongoing operations + std::mutex ongoingOpsMtx_; + std::condition_variable cvOngoing_; + int ongoingOps_ {0}; + bool destroying_ {false}; }; } // namespace upnp -- GitLab