Enlighten me about cChunks
#1
We've had several people reporting crashes thanks to the PathFinder, all of them are related to cChunks.

Can someone explain what to expect and what not to expect when it comes to chunks?
  • Is it safe to assume that a Tick()'s chunk is valid?
  • Is it safe to call a_Chunk->GetNeighborChunk(a_Location.x, a_Location.z); when the chunk is invalid?
  • Assuming a valid pointer, could a_Chunk->GetNeighborChunk(a_Location.x, a_Location.z); crash the game under some circumstances?
  • A general explanation of the "safety instructions" of chunks would be appreciated.
Reply
Thanks given by:
#2
Generally, consider chunks a tri-state thing. Either you have a nullptr, which means you don't really have anything. Or you have a pointer to a cChunk, but the instance is not valid (IsValid() returns false, cpInvalid or cpQueued); this means that the chunk is allocated, but its data hasn't been loaded from disk / generated yet. And the third state is when the chunk is fully operational with all its data available (cpPresent).
Chunks are stored in a cChunkMap object, which takes care of the spatial management. It provides coord-to-cChunk mapping (using a two-level hierarchy, hence the cChunkMap::cChunkLayer class, which stores a 32 * 32 area of chunks) and has the master mutex for accessing the chunks. Chunks are accessed by various threads - the world tick thread, the generator thread, the world storage thread. Each of those locks the mutex, of course. This makes the mutex kinda central in the whole server; whenever there is a deadlock, you can be pretty sure that this mutex is involved.

The cChunk instance that is passed to cEntity::Tick() is always valid (because it's the chunk from whose Tick() method the entity's Tick method is called). However, the entity physics code moves the entity according to its speed, gravity etc., and this may move the entity out to a different chunk; that chunk is not guaranteed to be valid (we should fix this - disable moving into a chunk that is not cpPresent).

You should be able to call a_Chunk->GetNeighborChunk() whenever you have a cChunk instance, it doesn't need to even be a valid (loaded) chunk. But note that it may return a nullptr when it cannot reach the neighbor. The function should never crash for any input data.
Reply
Thanks given by: LogicParrot
#3
And yet it did.
Reply
Thanks given by:
#4
And are you sure you're calling it on a valid cChunk pointer?
(reinterpret_cast<cChunk *>(nullptr))->GetNeighborChunk(x, y)
Reply
Thanks given by:
#5
I'm not sure of the version the guy used, so I cannot say. In the latest it's a chunk reference passed by the tick, so it's probably valid.
What's that snippet? Didn't get it.
Reply
Thanks given by:




Users browsing this thread: 4 Guest(s)