mirror of
https://github.com/minetest/minetest.git
synced 2024-12-22 22:22:23 +01:00
Switch env lock to fair mutex implementation
This commit is contained in:
parent
0220d0d492
commit
5f308deb50
@ -35,6 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "util/metricsbackend.h"
|
#include "util/metricsbackend.h"
|
||||||
#include "serverenvironment.h"
|
#include "serverenvironment.h"
|
||||||
#include "server/clientiface.h"
|
#include "server/clientiface.h"
|
||||||
|
#include "threading/ordered_mutex.h"
|
||||||
#include "chatmessage.h"
|
#include "chatmessage.h"
|
||||||
#include "sound.h"
|
#include "sound.h"
|
||||||
#include "translation.h"
|
#include "translation.h"
|
||||||
@ -430,7 +431,7 @@ public:
|
|||||||
EnvAutoLock(Server *server): m_lock(server->m_env_mutex) {}
|
EnvAutoLock(Server *server): m_lock(server->m_env_mutex) {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MutexAutoLock m_lock;
|
std::lock_guard<ordered_mutex> m_lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -608,7 +609,7 @@ private:
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// Environment mutex (envlock)
|
// Environment mutex (envlock)
|
||||||
std::mutex m_env_mutex;
|
ordered_mutex m_env_mutex;
|
||||||
|
|
||||||
// World directory
|
// World directory
|
||||||
std::string m_path_world;
|
std::string m_path_world;
|
||||||
|
46
src/threading/ordered_mutex.h
Normal file
46
src/threading/ordered_mutex.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
// Minetest
|
||||||
|
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <condition_variable>
|
||||||
|
|
||||||
|
/*
|
||||||
|
Fair mutex based on ticketing approach.
|
||||||
|
Satisfies `Mutex` C++11 requirements.
|
||||||
|
*/
|
||||||
|
class ordered_mutex {
|
||||||
|
public:
|
||||||
|
ordered_mutex() : next_ticket(0), counter(0) {}
|
||||||
|
|
||||||
|
void lock()
|
||||||
|
{
|
||||||
|
std::unique_lock autolock(cv_lock);
|
||||||
|
const auto ticket = next_ticket++;
|
||||||
|
cv.wait(autolock, [&] { return counter == ticket; });
|
||||||
|
}
|
||||||
|
|
||||||
|
bool try_lock()
|
||||||
|
{
|
||||||
|
std::lock_guard autolock(cv_lock);
|
||||||
|
if (counter != next_ticket)
|
||||||
|
return false;
|
||||||
|
next_ticket++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void unlock()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
std::lock_guard autolock(cv_lock);
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
cv.notify_all(); // intentionally outside lock
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::condition_variable cv;
|
||||||
|
std::mutex cv_lock;
|
||||||
|
uint_fast32_t next_ticket, counter;
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user