World: fixed assertion failure when requesting, cancelling, and then re-requesting chunks via requestChunkPopulation()

if the request/cancel/re-request happens all in the time before the queue gets drained, chunk hashes may appear multiple times in the queue. We don't want to process them twice if this happens (although it's mostly harmless anyway).
This commit is contained in:
Dylan K. Taylor 2021-11-01 02:17:11 +00:00
parent 46b7d35cd3
commit 9d30bc8b95
No known key found for this signature in database
GPG Key ID: 8927471A91CAFD3D

View File

@ -2760,8 +2760,17 @@ class World implements ChunkManager{
private function drainPopulationRequestQueue() : void{
$failed = [];
$seen = [];
while(count($this->activeChunkPopulationTasks) < $this->maxConcurrentChunkPopulationTasks && !$this->chunkPopulationRequestQueue->isEmpty()){
$nextChunkHash = $this->chunkPopulationRequestQueue->dequeue();
if(isset($seen[$nextChunkHash])){
//We may have previously requested this, decided we didn't want it, and then decided we did want it
//again, all before the generation request got executed. In that case, the chunk hash may appear in the
//queue multiple times (it can't be quickly removed from the queue when the request is cancelled, so we
//leave it in the queue).
continue;
}
$seen[$nextChunkHash] = true;
World::getXZ($nextChunkHash, $nextChunkX, $nextChunkZ);
if(isset($this->chunkPopulationRequestMap[$nextChunkHash])){
assert(!isset($this->activeChunkPopulationTasks[$nextChunkHash]), "Population for chunk $nextChunkX $nextChunkZ already running");