From: bert hubert Date: Thu, 20 Mar 2014 08:15:33 +0000 (+0100) Subject: we had a deadly embrace in getUpdatedMasters in bindbackend reimplementation, thanks... X-Git-Tag: rec-3.6.0-rc1~118 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9215e60fc1e71cbcae8ab93ab6ce20ada09e77da;p=thirdparty%2Fpdns.git we had a deadly embrace in getUpdatedMasters in bindbackend reimplementation, thanks to Winfried for detailed debugging! --- diff --git a/modules/bindbackend/bindbackend2.cc b/modules/bindbackend/bindbackend2.cc index c5a18b1dc4..1bb72320df 100644 --- a/modules/bindbackend/bindbackend2.cc +++ b/modules/bindbackend/bindbackend2.cc @@ -290,35 +290,41 @@ bool Bind2Backend::feedRecord(const DNSResourceRecord &r, string *ordername) void Bind2Backend::getUpdatedMasters(vector *changedDomains) { - SOAData soadata; - ReadLock rl(&s_state_lock); + vector toPut; + { + ReadLock rl(&s_state_lock); + SOAData soadata; - for(state_t::const_iterator i = s_state.begin(); i != s_state.end() ; ++i) { - if(!i->d_masters.empty() && this->alsoNotify.empty() && i->d_also_notify.empty()) - continue; - soadata.serial=0; - try { - this->getSOA(i->d_name, soadata); // we might not *have* a SOA yet, but this might trigger a load of it - } - catch(...){} - DomainInfo di; - di.id=i->d_id; - di.serial=soadata.serial; - di.zone=i->d_name; - di.last_check=i->d_lastcheck; - di.backend=this; - di.kind=DomainInfo::Master; - if(!i->d_lastnotified) { // don't do notification storm on startup - // what if i->first is new?? - BB2DomainInfo bbd; - if(safeGetBBDomainInfo(i->d_id, &bbd)) { - bbd.d_lastnotified=soadata.serial; - safePutBBDomainInfo(bbd); + for(state_t::const_iterator i = s_state.begin(); i != s_state.end() ; ++i) { + if(!i->d_masters.empty() && this->alsoNotify.empty() && i->d_also_notify.empty()) + continue; + soadata.serial=0; + try { + this->getSOA(i->d_name, soadata); // we might not *have* a SOA yet, but this might trigger a load of it + } + catch(...){} + DomainInfo di; + di.id=i->d_id; + di.serial=soadata.serial; + di.zone=i->d_name; + di.last_check=i->d_lastcheck; + di.backend=this; + di.kind=DomainInfo::Master; + if(!i->d_lastnotified) { // don't do notification storm on startup + // what if i->first is new?? + BB2DomainInfo bbd; + if(safeGetBBDomainInfo(i->d_id, &bbd)) { // we hold a readlock, so this is fine + bbd.d_lastnotified=soadata.serial; + toPut.push_back(bbd); // but we can't write yet + } } + else + if(soadata.serial != i->d_lastnotified) + changedDomains->push_back(di); } - else - if(soadata.serial != i->d_lastnotified) - changedDomains->push_back(di); + } + BOOST_FOREACH(BB2DomainInfo& bbd, toPut) { + safePutBBDomainInfo(bbd); } }