sObjectMgr thread safety question

How thread-safe is sObjectMgr?

For example, if I were to create a command what changes some property of a gameobject (essentially changing gameobject data from GameObjectDataContainer _gameObjectDataStore), would it cause problems if this command or action was done multiple times at the same time? Would I need to wrap data-changing action around mutex-locking to prevent such problems if they would arise?

Thanks in advance!

you have to consider if the command will be executed in a thread-safe environment or not too

ObjectMgr usage across multiple threads is not thread safe for obvious reasons unless otherwise locked by a mutex. That being said, if all you plan on doing is creating a command just know that commands are executed solely in World::UpdateSessions, which is single threaded.

tl;dr: If all you're doing is chat commands, you don't need to worry about thread safety.

Isn’t sObjectMgr used outside of commands, though? Like map updates or something of the sort? I still haven’t gotten full grasp of how every corner of TC works, so sorry if I assume something wrong.

The way the threading works -as far as I know- is that there is a main loop and at one point of it a pool of threads is used to update maps in parallel to eachother.
All other parts of the main server loop should be single threaded except that map update part.
As already said, commands are handled in one part of that main loop when the maps are not being updated.

There are some other threads, but they can be for example: freeze detector and the threads for executing async SQL queries - but they are not needed to be concerned about since they dont use objectmgr etc.

Are client messages handled in the same way, then? For example, when a server receives a client message to execute a command or handle some other simple OpCode, does the server just queue it up on some global queue, which is handled on a single thread or does it split the request off in a separate new thread to handle it (as in, each client request gets its own thread)?

Once again, thank you everyone for answering questions :slight_smile:

A non global (define global : D) worldsession specific que is used to queue packets for the worldsession (player session). As already said, the commands, thus the command and chat packets, are handled in the World::UpdateSessions part.

See https://github.com/TrinityCore/TrinityCore/blob/575d5f5ff803790bc097d16a3f1e86f3eda5318e/src/server/game/Server/WorldSession.h#L1757

Most opcodes are processed by the single threaded World updater (using a single locked queue for each worldsession for both updaters), however there’s a few that are processed in the Map updater, which is thread unsafe (but it’s mainly just movement and spell opcodes which are designed to be thread safe and map specific). You can check which updater processes opcodes by checking the PROCESS_XXXX flag in Opcodes.cpp and it’ll tell you whether the opcode is thread safe handled or not. If needed I can probably draw something up in paint for a visual description of how TrinityCore’s threads work.

Here's the PacketProcessing enum which should help as well: [https://github.com/TrinityCore/TrinityCore/blob/6.x/src/server/game/Server/Protocol/Opcodes.h#L1683-L1688](https://github.com/TrinityCore/TrinityCore/blob/6.x/src/server/game/Server/Protocol/Opcodes.h#L1683-L1688)

Alright, I think I got the idea now how the threading works. Thanks everyone!