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
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 @@
 
     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 @@
 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 @@
             }
         });
     }
+    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 @@
 
     // Shutdown synchronization
     bool shutdownComplete_ {false};
+
+    // Count ongoing operations
+    std::mutex ongoingOpsMtx_;
+    std::condition_variable cvOngoing_;
+    int ongoingOps_ {0};
+    bool destroying_ {false};
 };
 
 } // namespace upnp