datasrc::ConfigurableClientList& client_list,
const dns::RRClass& rrclass, const dns::Name& origin)
{
- const datasrc::ConfigurableClientList::ZoneWriterPair writerpair =
- client_list.getCachedZoneWriter(origin);
+ // getCachedZoneWriter() could get access to an underlying data source
+ // that can cause a race condition with the main thread using that data
+ // source for lookup. So we need to protect the access here.
+ datasrc::ConfigurableClientList::ZoneWriterPair writerpair;
+ {
+ typename MutexType::Locker locker(*map_mutex_);
+ writerpair = client_list.getCachedZoneWriter(origin);
+ }
switch (writerpair.first) {
case datasrc::ConfigurableClientList::ZONE_SUCCESS:
"{\"class\": \"IN\","
" \"origin\": \"test1.example\"}"));
EXPECT_TRUE(builder.handleCommand(loadzone_cmd));
- EXPECT_EQ(1, map_mutex.lock_count); // we should have acquired the lock
- EXPECT_EQ(1, map_mutex.unlock_count); // and released it.
+
+ // loadZone involves two critical sections: one for getting the zone
+ // writer, and one for actually updating the zone data. So the lock/unlock
+ // count should be incremented by 2.
+ EXPECT_EQ(2, map_mutex.lock_count);
+ EXPECT_EQ(2, map_mutex.unlock_count);
newZoneChecks(clients_map, rrclass);
}