void NetDbRequests::ManageRequests() { uint64_t ts = i2p::util::GetSecondsSinceEpoch(); std::unique_lock<std::mutex> l(m_RequestedDestinationsMutex); for (auto it = m_RequestedDestinations.begin(); it != m_RequestedDestinations.end();) { auto& dest = it->second; bool done = false; // request is worthless after 1 minute if (ts < dest->GetCreationTime() + 60) { // no response for 5 seconds if (ts > dest->GetCreationTime() + 5) { auto count = dest->GetExcludedPeers().size(); std::size_t attempts(7); if (!dest->IsExploratory() && count < attempts) { auto pool = i2p::tunnel::tunnels.GetExploratoryPool(); auto outbound = pool->GetNextOutboundTunnel(); auto inbound = pool->GetNextInboundTunnel(); auto nextFloodfill = netdb.GetClosestFloodfill( dest->GetDestination(), dest->GetExcludedPeers()); if (nextFloodfill && outbound && inbound) { outbound->SendTunnelDataMsg( nextFloodfill->GetIdentHash(), 0, dest->CreateRequestMessage( nextFloodfill, inbound)); } else { done = true; if (!inbound) LogPrint(eLogWarn, "NetDbRequests: no inbound tunnels"); if (!outbound) LogPrint(eLogWarn, "NetDbRequests: no outbound tunnels"); if (!nextFloodfill) LogPrint(eLogWarn, "NetDbRequests: no more floodfills"); } } else { if (!dest->IsExploratory()) LogPrint(eLogWarn, "NetDbRequests: ", dest->GetDestination().ToBase64(), " not found after ", attempts, " attempts"); done = true; } } } else { // delete obsolete request done = true; } if (done) it = m_RequestedDestinations.erase(it); else it++; } }
void fillLevel( FreeListHelper & helper, Level & level, uint32_t & seed ) { level.rooms.reserve( configuration_.numRooms ); #ifdef FL_DEBUG log() << "Attempting to fill level." << std::endl; #endif helper.resetFreeEntryCache(); uint32_t compactionCount( 0 ); bool spaceAvailable( true ); uint32_t roomsCreated( 0 ); uint32_t attempts( 0 ); while( spaceAvailable ) { while( spaceAvailable ) { vec4uint32 newRoomDimensions = makePositionlessRoom_( seed ); if( helper.canInsertRoom( level, newRoomDimensions, seed ) ) { #ifdef FL_DEBUG log() << "Inserting room " << roomsCreated << std::endl; #endif roomsCreated++; uint8_t rgb[3]; rgb[0] = 64 + ( randGenerator_( seed ) % 128); rgb[1] = 64 + ( randGenerator_( seed ) % 128); rgb[2] = 64 + ( randGenerator_( seed ) % 128); level.rooms.emplace_back( seed, newRoomDimensions, rgb ); if( roomsCreated >= configuration_.numRooms ) { #ifdef FL_DEBUG log() << "Number of rooms satisfied" << std::endl; #endif goto DONE; } attempts = 0; } else { attempts++; if( attempts >= configuration_.maxRoomAttempts ) { #ifdef FL_DEBUG log() << "Exceeded number of room creation attempts" << std::endl; #endif // If we haven't already tried to compact the free space // try that if( compactionCount == 0 ) { #ifdef FL_DEBUG log() << "Haven't tried computing free lists yet, will do that first" << std::endl; #endif attempts = 0; goto COMPUTE_FREE_LISTS; } else { #ifdef FL_DEBUG log() << "Already tried computing free list so will stop" << std::endl; #endif goto DONE; } } } spaceAvailable = helper.hasFreeSpace(); } COMPUTE_FREE_LISTS: // Exhausted current free lists, compact free space using flood fill #ifdef FL_DEBUG log() << "Compacting free space" << std::endl; #endif spaceAvailable = helper.computeFreeLists(); compactionCount++; } #ifdef FL_DEBUG log() << "All possible space taken." << std::endl; #endif DONE: #ifdef FL_DEBUG helper.debugFreeLists(); #endif level.fillTiles(); }