Encapsulate envlock

This commit is contained in:
sfan5 2024-09-15 21:25:03 +02:00
parent 588a0f83e9
commit 0220d0d492
4 changed files with 31 additions and 22 deletions

@ -540,7 +540,7 @@ bool EmergeThread::popBlockEmerge(v3s16 *pos, BlockEmergeData *bedata)
EmergeAction EmergeThread::getBlockOrStartGen(const v3s16 pos, bool allow_gen, EmergeAction EmergeThread::getBlockOrStartGen(const v3s16 pos, bool allow_gen,
const std::string *from_db, MapBlock **block, BlockMakeData *bmdata) const std::string *from_db, MapBlock **block, BlockMakeData *bmdata)
{ {
MutexAutoLock envlock(m_server->m_env_mutex); Server::EnvAutoLock envlock(m_server);
auto block_ok = [] (MapBlock *b) { auto block_ok = [] (MapBlock *b) {
return b && b->isGenerated(); return b && b->isGenerated();
@ -581,7 +581,7 @@ EmergeAction EmergeThread::getBlockOrStartGen(const v3s16 pos, bool allow_gen,
MapBlock *EmergeThread::finishGen(v3s16 pos, BlockMakeData *bmdata, MapBlock *EmergeThread::finishGen(v3s16 pos, BlockMakeData *bmdata,
std::map<v3s16, MapBlock *> *modified_blocks) std::map<v3s16, MapBlock *> *modified_blocks)
{ {
MutexAutoLock envlock(m_server->m_env_mutex); Server::EnvAutoLock envlock(m_server);
ScopeProfiler sp(g_profiler, ScopeProfiler sp(g_profiler,
"EmergeThread: after Mapgen::makeChunk", SPT_AVG); "EmergeThread: after Mapgen::makeChunk", SPT_AVG);
@ -762,7 +762,7 @@ void *EmergeThread::run()
MapEditEvent event; MapEditEvent event;
event.type = MEET_OTHER; event.type = MEET_OTHER;
event.setModifiedBlocks(modified_blocks); event.setModifiedBlocks(modified_blocks);
MutexAutoLock envlock(m_server->m_env_mutex); Server::EnvAutoLock envlock(m_server);
m_map->dispatchEvent(event); m_map->dispatchEvent(event);
} }
modified_blocks.clear(); modified_blocks.clear();

@ -160,7 +160,7 @@ void LuaEmergeAreaCallback(v3s16 blockpos, EmergeAction action, void *param)
// state must be protected by envlock // state must be protected by envlock
Server *server = state->script->getServer(); Server *server = state->script->getServer();
MutexAutoLock envlock(server->m_env_mutex); Server::EnvAutoLock envlock(server);
state->refcount--; state->refcount--;

@ -353,7 +353,7 @@ Server::~Server()
m_emerge->stopThreads(); m_emerge->stopThreads();
if (m_env) { if (m_env) {
MutexAutoLock envlock(m_env_mutex); EnvAutoLock envlock(this);
infostream << "Server: Executing shutdown hooks" << std::endl; infostream << "Server: Executing shutdown hooks" << std::endl;
try { try {
@ -461,7 +461,7 @@ void Server::init()
} }
//lock environment //lock environment
MutexAutoLock envlock(m_env_mutex); EnvAutoLock envlock(this);
// Create the Map (loads map_meta.txt, overriding configured mapgen params) // Create the Map (loads map_meta.txt, overriding configured mapgen params)
auto startup_server_map = std::make_unique<ServerMap>(m_path_world, this, auto startup_server_map = std::make_unique<ServerMap>(m_path_world, this,
@ -653,7 +653,7 @@ void Server::AsyncRunStep(float dtime, bool initial_step)
} }
{ {
MutexAutoLock lock(m_env_mutex); EnvAutoLock lock(this);
float max_lag = m_env->getMaxLagEstimate(); float max_lag = m_env->getMaxLagEstimate();
constexpr float lag_warn_threshold = 2.0f; constexpr float lag_warn_threshold = 2.0f;
@ -686,7 +686,7 @@ void Server::AsyncRunStep(float dtime, bool initial_step)
static const float map_timer_and_unload_dtime = 2.92; static const float map_timer_and_unload_dtime = 2.92;
if(m_map_timer_and_unload_interval.step(dtime, map_timer_and_unload_dtime)) if(m_map_timer_and_unload_interval.step(dtime, map_timer_and_unload_dtime))
{ {
MutexAutoLock lock(m_env_mutex); EnvAutoLock lock(this);
// Run Map's timers and unload unused data // Run Map's timers and unload unused data
ScopeProfiler sp(g_profiler, "Server: map timer and unload"); ScopeProfiler sp(g_profiler, "Server: map timer and unload");
m_env->getMap().timerUpdate(map_timer_and_unload_dtime, m_env->getMap().timerUpdate(map_timer_and_unload_dtime,
@ -704,7 +704,7 @@ void Server::AsyncRunStep(float dtime, bool initial_step)
*/ */
if (m_admin_chat) { if (m_admin_chat) {
if (!m_admin_chat->command_queue.empty()) { if (!m_admin_chat->command_queue.empty()) {
MutexAutoLock lock(m_env_mutex); EnvAutoLock lock(this);
while (!m_admin_chat->command_queue.empty()) { while (!m_admin_chat->command_queue.empty()) {
ChatEvent *evt = m_admin_chat->command_queue.pop_frontNoEx(); ChatEvent *evt = m_admin_chat->command_queue.pop_frontNoEx();
handleChatInterfaceEvent(evt); handleChatInterfaceEvent(evt);
@ -725,7 +725,7 @@ void Server::AsyncRunStep(float dtime, bool initial_step)
{ {
m_liquid_transform_timer -= m_liquid_transform_every; m_liquid_transform_timer -= m_liquid_transform_every;
MutexAutoLock lock(m_env_mutex); EnvAutoLock lock(this);
ScopeProfiler sp(g_profiler, "Server: liquid transform"); ScopeProfiler sp(g_profiler, "Server: liquid transform");
@ -786,7 +786,7 @@ void Server::AsyncRunStep(float dtime, bool initial_step)
*/ */
{ {
//infostream<<"Server: Checking added and deleted active objects"<<std::endl; //infostream<<"Server: Checking added and deleted active objects"<<std::endl;
MutexAutoLock envlock(m_env_mutex); EnvAutoLock envlock(this);
// This guarantees that each object recomputes its cache only once per server step, // This guarantees that each object recomputes its cache only once per server step,
// unless get_effective_observers is called. // unless get_effective_observers is called.
@ -831,7 +831,7 @@ void Server::AsyncRunStep(float dtime, bool initial_step)
Send object messages Send object messages
*/ */
{ {
MutexAutoLock envlock(m_env_mutex); EnvAutoLock envlock(this);
ScopeProfiler sp(g_profiler, "Server: send SAO messages"); ScopeProfiler sp(g_profiler, "Server: send SAO messages");
// Key = object id // Key = object id
@ -933,7 +933,7 @@ void Server::AsyncRunStep(float dtime, bool initial_step)
*/ */
{ {
// We will be accessing the environment // We will be accessing the environment
MutexAutoLock lock(m_env_mutex); EnvAutoLock lock(this);
// Single change sending is disabled if queue size is big // Single change sending is disabled if queue size is big
bool disable_single_change_sending = false; bool disable_single_change_sending = false;
@ -1040,7 +1040,7 @@ void Server::AsyncRunStep(float dtime, bool initial_step)
g_settings->getFloat("server_map_save_interval"); g_settings->getFloat("server_map_save_interval");
if (counter >= save_interval) { if (counter >= save_interval) {
counter = 0.0; counter = 0.0;
MutexAutoLock lock(m_env_mutex); EnvAutoLock lock(this);
ScopeProfiler sp(g_profiler, "Server: map saving (sum)"); ScopeProfiler sp(g_profiler, "Server: map saving (sum)");
@ -1191,7 +1191,7 @@ inline void Server::handleCommand(NetworkPacket *pkt)
void Server::ProcessData(NetworkPacket *pkt) void Server::ProcessData(NetworkPacket *pkt)
{ {
// Environment is locked first. // Environment is locked first.
MutexAutoLock envlock(m_env_mutex); EnvAutoLock envlock(this);
ScopeProfiler sp(g_profiler, "Server: Process network packet (sum)"); ScopeProfiler sp(g_profiler, "Server: Process network packet (sum)");
u32 peer_id = pkt->getPeerId(); u32 peer_id = pkt->getPeerId();
@ -2363,8 +2363,7 @@ void Server::SendBlockNoLock(session_t peer_id, MapBlock *block, u8 ver,
void Server::SendBlocks(float dtime) void Server::SendBlocks(float dtime)
{ {
MutexAutoLock envlock(m_env_mutex); EnvAutoLock envlock(this);
//TODO check if one big lock could be faster then multiple small ones
std::vector<PrioritySortedBlockTransfer> queue; std::vector<PrioritySortedBlockTransfer> queue;
@ -2695,7 +2694,7 @@ void Server::sendRequestedMedia(session_t peer_id,
void Server::stepPendingDynMediaCallbacks(float dtime) void Server::stepPendingDynMediaCallbacks(float dtime)
{ {
MutexAutoLock lock(m_env_mutex); EnvAutoLock lock(this);
for (auto it = m_pending_dyn_media.begin(); it != m_pending_dyn_media.end();) { for (auto it = m_pending_dyn_media.begin(); it != m_pending_dyn_media.end();) {
it->second.expiry_timer -= dtime; it->second.expiry_timer -= dtime;
@ -2914,7 +2913,7 @@ void Server::DeleteClient(session_t peer_id, ClientDeletionReason reason)
} }
} }
{ {
MutexAutoLock env_lock(m_env_mutex); EnvAutoLock envlock(this);
m_clients.DeleteClient(peer_id); m_clients.DeleteClient(peer_id);
} }
} }
@ -4107,7 +4106,7 @@ Translations *Server::getTranslationLanguage(const std::string &lang_code)
std::unordered_map<std::string, std::string> Server::getMediaList() std::unordered_map<std::string, std::string> Server::getMediaList()
{ {
MutexAutoLock env_lock(m_env_mutex); EnvAutoLock envlock(this);
std::unordered_map<std::string, std::string> ret; std::unordered_map<std::string, std::string> ret;
for (auto &it : m_media) { for (auto &it : m_media) {

@ -424,8 +424,14 @@ public:
// Bind address // Bind address
Address m_bind_addr; Address m_bind_addr;
// Environment mutex (envlock) // Public helper for taking the envlock in a scope
std::mutex m_env_mutex; class EnvAutoLock {
public:
EnvAutoLock(Server *server): m_lock(server->m_env_mutex) {}
private:
MutexAutoLock m_lock;
};
protected: protected:
/* Do not add more members here, this is only required to make unit tests work. */ /* Do not add more members here, this is only required to make unit tests work. */
@ -600,6 +606,10 @@ private:
/* /*
Variables Variables
*/ */
// Environment mutex (envlock)
std::mutex m_env_mutex;
// World directory // World directory
std::string m_path_world; std::string m_path_world;
std::string m_path_mod_data; std::string m_path_mod_data;