Commit bf1dfb91 authored by Adrien Béraud's avatar Adrien Béraud

pupnp: wait on condition

Change-Id: I053ca22980267a8e2fd04e73e9a0c1e4a1064248
parent eb7bde60
...@@ -86,54 +86,63 @@ PUPnP::PUPnP() ...@@ -86,54 +86,63 @@ PUPnP::PUPnP()
pupnpThread_ = std::thread([this] { pupnpThread_ = std::thread([this] {
std::unique_lock<std::mutex> lk(ctrlptMutex_); std::unique_lock<std::mutex> lk(ctrlptMutex_);
while (pupnpRun_) { while (pupnpRun_) {
pupnpCv_.wait(lk); pupnpCv_.wait(lk, [this]{
return not clientRegistered_ or
not pupnpRun_ or
searchForIgd_ or
not dwnldlXmlList_.empty();
});
if (not clientRegistered_) { if (not clientRegistered_) {
// Register Upnp control point. // Register Upnp control point.
int upnp_err = UpnpRegisterClient(ctrlPtCallback, this, &ctrlptHandle_); int upnp_err = UpnpRegisterClient(ctrlPtCallback, this, &ctrlptHandle_);
if (upnp_err != UPNP_E_SUCCESS) if (upnp_err != UPNP_E_SUCCESS) {
JAMI_ERR("PUPnP: Can't register client: %s", UpnpGetErrorMessage(upnp_err)); JAMI_ERR("PUPnP: Can't register client: %s", UpnpGetErrorMessage(upnp_err));
else pupnpRun_ = false;
break;
} else
clientRegistered_ = true; clientRegistered_ = true;
} }
if (not pupnpRun_) if (not pupnpRun_)
break; break;
if (clientRegistered_ and searchForIgd_) {
// Send out search for multiple types of devices, as some routers may possibly only reply to one.
UpnpSearchAsync(ctrlptHandle_, SEARCH_TIMEOUT, UPNP_ROOT_DEVICE, this);
UpnpSearchAsync(ctrlptHandle_, SEARCH_TIMEOUT, UPNP_IGD_DEVICE, this);
UpnpSearchAsync(ctrlptHandle_, SEARCH_TIMEOUT, UPNP_WANIP_SERVICE, this);
UpnpSearchAsync(ctrlptHandle_, SEARCH_TIMEOUT, UPNP_WANPPP_SERVICE, this);
// Reset variable.
searchForIgd_ = false;
}
if (clientRegistered_) { if (clientRegistered_) {
auto xmlList = std::move(dwnldlXmlList_); if (searchForIgd_) {
decltype(xmlList) finished {}; // Send out search for multiple types of devices, as some routers may possibly only reply to one.
UpnpSearchAsync(ctrlptHandle_, SEARCH_TIMEOUT, UPNP_ROOT_DEVICE, this);
// Wait on futures asynchronously UpnpSearchAsync(ctrlptHandle_, SEARCH_TIMEOUT, UPNP_IGD_DEVICE, this);
lk.unlock(); UpnpSearchAsync(ctrlptHandle_, SEARCH_TIMEOUT, UPNP_WANIP_SERVICE, this);
for (auto it = xmlList.begin(); it != xmlList.end();) { UpnpSearchAsync(ctrlptHandle_, SEARCH_TIMEOUT, UPNP_WANPPP_SERVICE, this);
if (it->wait_for(std::chrono::seconds(1)) == std::future_status::ready) {
finished.splice(finished.end(), xmlList, it++); // Reset variable.
} else { searchForIgd_ = false;
JAMI_WARN("PUPnP: XML download timed out");
++it;
}
} }
lk.lock();
if (not dwnldlXmlList_.empty()) {
// Move back failed items to end of list auto xmlList = std::move(dwnldlXmlList_);
dwnldlXmlList_.splice(dwnldlXmlList_.end(), xmlList); decltype(xmlList) finished {};
// Handle successful downloads
for (auto& item : finished) { // Wait on futures asynchronously
auto result = item.get(); lk.unlock();
if (not result.document or not validateIgd(result)) { for (auto it = xmlList.begin(); it != xmlList.end();) {
cpDeviceList_.erase(result.location); if (it->wait_for(std::chrono::seconds(1)) == std::future_status::ready) {
finished.splice(finished.end(), xmlList, it++);
} else {
JAMI_WARN("PUPnP: XML download timed out");
++it;
}
}
lk.lock();
// Move back failed items to end of list
dwnldlXmlList_.splice(dwnldlXmlList_.end(), xmlList);
// Handle successful downloads
for (auto& item : finished) {
auto result = item.get();
if (not result.document or not validateIgd(result)) {
cpDeviceList_.erase(result.location);
}
} }
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment