Replace all CRITICAL_SECTION usage with std::mutex and std::lock_guard

Migrates 59 files from WinAPI CRITICAL_SECTION to portable C++ std::mutex/std::lock_guard/std::unique_lock. Removes Linux CRITICAL_SECTION shims from winapi_stubs.h.
This commit is contained in:
MatthewBeshay 2026-03-30 18:45:55 +11:00
parent c772cfe8b3
commit bc6013ab70
59 changed files with 952 additions and 1128 deletions

View file

@ -1,4 +1,5 @@
#include "../Platform/stdafx.h"
#include <mutex>
#include "MultiPlayerLevel.h"
#include "../Player/MultiPlayerLocalPlayer.h"
#include "../Network/ClientConnection.h"
@ -117,14 +118,15 @@ void MultiPlayerLevel::tick() {
PIXEndNamedEvent();
PIXBeginNamedEvent(0, "Entity re-entry");
EnterCriticalSection(&m_entitiesCS);
for (int i = 0; i < 10 && !reEntries.empty(); i++) {
std::shared_ptr<Entity> e = *(reEntries.begin());
{
std::lock_guard<std::recursive_mutex> lock(m_entitiesCS);
for (int i = 0; i < 10 && !reEntries.empty(); i++) {
std::shared_ptr<Entity> e = *(reEntries.begin());
if (find(entities.begin(), entities.end(), e) == entities.end())
addEntity(e);
if (find(entities.begin(), entities.end(), e) == entities.end())
addEntity(e);
}
}
LeaveCriticalSection(&m_entitiesCS);
PIXEndNamedEvent();
PIXBeginNamedEvent(0, "Connection ticking");
@ -808,23 +810,24 @@ void MultiPlayerLevel::setDayTime(int64_t newTime) {
void MultiPlayerLevel::removeAllPendingEntityRemovals() {
// entities.removeAll(entitiesToRemove);
EnterCriticalSection(&m_entitiesCS);
for (auto it = entities.begin(); it != entities.end();) {
bool found = false;
for (auto it2 = entitiesToRemove.begin();
it2 != entitiesToRemove.end(); it2++) {
if ((*it) == (*it2)) {
found = true;
break;
{
std::lock_guard<std::recursive_mutex> lock(m_entitiesCS);
for (auto it = entities.begin(); it != entities.end();) {
bool found = false;
for (auto it2 = entitiesToRemove.begin();
it2 != entitiesToRemove.end(); it2++) {
if ((*it) == (*it2)) {
found = true;
break;
}
}
if (found) {
it = entities.erase(it);
} else {
it++;
}
}
if (found) {
it = entities.erase(it);
} else {
it++;
}
}
LeaveCriticalSection(&m_entitiesCS);
auto endIt = entitiesToRemove.end();
for (auto it = entitiesToRemove.begin(); it != endIt; it++) {
@ -845,36 +848,37 @@ void MultiPlayerLevel::removeAllPendingEntityRemovals() {
entitiesToRemove.clear();
// for (int i = 0; i < entities.size(); i++)
EnterCriticalSection(&m_entitiesCS);
std::vector<std::shared_ptr<Entity> >::iterator it = entities.begin();
while (it != entities.end()) {
std::shared_ptr<Entity> e = *it; // entities.at(i);
{
std::lock_guard<std::recursive_mutex> lock(m_entitiesCS);
std::vector<std::shared_ptr<Entity> >::iterator it = entities.begin();
while (it != entities.end()) {
std::shared_ptr<Entity> e = *it; // entities.at(i);
if (e->riding != nullptr) {
if (e->riding->removed || e->riding->rider.lock() != e) {
e->riding->rider = std::weak_ptr<Entity>();
e->riding = nullptr;
if (e->riding != nullptr) {
if (e->riding->removed || e->riding->rider.lock() != e) {
e->riding->rider = std::weak_ptr<Entity>();
e->riding = nullptr;
} else {
++it;
continue;
}
}
if (e->removed) {
int xc = e->xChunk;
int zc = e->zChunk;
if (e->inChunk && hasChunk(xc, zc)) {
getChunk(xc, zc)->removeEntity(e);
}
// entities.remove(i--);
it = entities.erase(it);
entityRemoved(e);
} else {
++it;
continue;
it++;
}
}
if (e->removed) {
int xc = e->xChunk;
int zc = e->zChunk;
if (e->inChunk && hasChunk(xc, zc)) {
getChunk(xc, zc)->removeEntity(e);
}
// entities.remove(i--);
it = entities.erase(it);
entityRemoved(e);
} else {
it++;
}
}
LeaveCriticalSection(&m_entitiesCS);
}
void MultiPlayerLevel::removeClientConnection(ClientConnection* c,
@ -907,34 +911,34 @@ void MultiPlayerLevel::dataReceivedForChunk(int x, int z) {
void MultiPlayerLevel::removeUnusedTileEntitiesInRegion(int x0, int y0, int z0,
int x1, int y1,
int z1) {
EnterCriticalSection(&m_tileEntityListCS);
{
std::lock_guard<std::recursive_mutex> lock(m_tileEntityListCS);
for (unsigned int i = 0; i < tileEntityList.size();) {
bool removed = false;
std::shared_ptr<TileEntity> te = tileEntityList[i];
if (te->x >= x0 && te->y >= y0 && te->z >= z0 && te->x < x1 &&
te->y < y1 && te->z < z1) {
LevelChunk* lc = getChunk(te->x >> 4, te->z >> 4);
if (lc != nullptr) {
// Only remove tile entities where this is no longer a tile
// entity
int tileId = lc->getTile(te->x & 15, te->y, te->z & 15);
if (Tile::tiles[tileId] == nullptr ||
!Tile::tiles[tileId]->isEntityTile()) {
tileEntityList[i] = tileEntityList.back();
tileEntityList.pop_back();
for (unsigned int i = 0; i < tileEntityList.size();) {
bool removed = false;
std::shared_ptr<TileEntity> te = tileEntityList[i];
if (te->x >= x0 && te->y >= y0 && te->z >= z0 && te->x < x1 &&
te->y < y1 && te->z < z1) {
LevelChunk* lc = getChunk(te->x >> 4, te->z >> 4);
if (lc != nullptr) {
// Only remove tile entities where this is no longer a tile
// entity
int tileId = lc->getTile(te->x & 15, te->y, te->z & 15);
if (Tile::tiles[tileId] == nullptr ||
!Tile::tiles[tileId]->isEntityTile()) {
tileEntityList[i] = tileEntityList.back();
tileEntityList.pop_back();
// 4J Stu - Chests can create new tile entities when being
// removed, so disable this
m_bDisableAddNewTileEntities = true;
lc->removeTileEntity(te->x & 15, te->y, te->z & 15);
m_bDisableAddNewTileEntities = false;
removed = true;
// 4J Stu - Chests can create new tile entities when being
// removed, so disable this
m_bDisableAddNewTileEntities = true;
lc->removeTileEntity(te->x & 15, te->y, te->z & 15);
m_bDisableAddNewTileEntities = false;
removed = true;
}
}
}
if (!removed) i++;
}
if (!removed) i++;
}
LeaveCriticalSection(&m_tileEntityListCS);
}

View file

@ -1,5 +1,6 @@
#include <thread>
#include <chrono>
#include <mutex>
#include "../Platform/stdafx.h"
#include "ServerLevel.h"
@ -45,7 +46,7 @@ WeighedTreasureArray ServerLevel::RANDOM_BONUS_ITEMS;
C4JThread* ServerLevel::m_updateThread = nullptr;
C4JThread::EventArray* ServerLevel::m_updateTrigger;
CRITICAL_SECTION ServerLevel::m_updateCS[3];
std::mutex ServerLevel::m_updateCS[3];
Level* ServerLevel::m_level[3];
int ServerLevel::m_updateChunkX[3][LEVEL_CHUNKS_TO_UPDATE_MAX];
@ -59,9 +60,6 @@ int ServerLevel::m_randValue[3];
void ServerLevel::staticCtor() {
m_updateTrigger = new C4JThread::EventArray(3);
InitializeCriticalSection(&m_updateCS[0]);
InitializeCriticalSection(&m_updateCS[1]);
InitializeCriticalSection(&m_updateCS[2]);
m_updateThread = new C4JThread(runUpdate, nullptr, "Tile update");
m_updateThread->SetProcessor(CPU_CORE_TILE_UPDATE);
@ -107,9 +105,6 @@ ServerLevel::ServerLevel(MinecraftServer* server,
LevelSettings* levelSettings)
: Level(levelStorage, levelName, levelSettings,
Dimension::getNew(dimension), false) {
InitializeCriticalSection(&m_limiterCS);
InitializeCriticalSection(&m_tickNextTickCS);
InitializeCriticalSection(&m_csQueueSendTileUpdates);
m_fallingTileCount = 0;
m_primedTntCount = 0;
@ -188,30 +183,24 @@ ServerLevel::~ServerLevel() {
delete portalForcer;
delete mobSpawner;
EnterCriticalSection(&m_csQueueSendTileUpdates);
for (auto it = m_queuedSendTileUpdates.begin();
it != m_queuedSendTileUpdates.end(); ++it) {
Pos* p = *it;
delete p;
{
std::lock_guard<std::mutex> lock(m_csQueueSendTileUpdates);
for (auto it = m_queuedSendTileUpdates.begin();
it != m_queuedSendTileUpdates.end(); ++it) {
Pos* p = *it;
delete p;
}
m_queuedSendTileUpdates.clear();
delete this->tracker; // MGH - added, we were losing about 500K going in
// and out the menus
delete this->chunkMap;
}
m_queuedSendTileUpdates.clear();
delete this->tracker; // MGH - added, we were losing about 500K going in
// and out the menus
delete this->chunkMap;
LeaveCriticalSection(&m_csQueueSendTileUpdates);
DeleteCriticalSection(&m_csQueueSendTileUpdates);
DeleteCriticalSection(&m_limiterCS);
DeleteCriticalSection(&m_tickNextTickCS);
// Make sure that the update thread isn't actually doing any updating
EnterCriticalSection(&m_updateCS[0]);
LeaveCriticalSection(&m_updateCS[0]);
EnterCriticalSection(&m_updateCS[1]);
LeaveCriticalSection(&m_updateCS[1]);
EnterCriticalSection(&m_updateCS[2]);
LeaveCriticalSection(&m_updateCS[2]);
{ std::lock_guard<std::mutex> lock(m_updateCS[0]); }
{ std::lock_guard<std::mutex> lock(m_updateCS[1]); }
{ std::lock_guard<std::mutex> lock(m_updateCS[2]); }
m_updateTrigger->ClearAll();
}
@ -450,31 +439,32 @@ void ServerLevel::tickTiles() {
unsigned int tickCount = 0;
EnterCriticalSection(&m_updateCS[iLev]);
// This section processes the tiles that need to be ticked, which we worked
// out in the previous tick (or haven't yet, if this is the first frame)
/*int grassTicks = 0;
int lavaTicks = 0;
int otherTicks = 0;*/
for (int i = 0; i < m_updateTileCount[iLev]; i++) {
int x = m_updateTileX[iLev][i];
int y = m_updateTileY[iLev][i];
int z = m_updateTileZ[iLev][i];
if (hasChunkAt(x, y, z)) {
int id = getTile(x, y, z);
if (Tile::tiles[id] != nullptr && Tile::tiles[id]->isTicking()) {
/*if(id == 2) ++grassTicks;
else if(id == 11) ++lavaTicks;
else ++otherTicks;*/
Tile::tiles[id]->tick(this, x, y, z, random);
{
std::lock_guard<std::mutex> lock(m_updateCS[iLev]);
// This section processes the tiles that need to be ticked, which we worked
// out in the previous tick (or haven't yet, if this is the first frame)
/*int grassTicks = 0;
int lavaTicks = 0;
int otherTicks = 0;*/
for (int i = 0; i < m_updateTileCount[iLev]; i++) {
int x = m_updateTileX[iLev][i];
int y = m_updateTileY[iLev][i];
int z = m_updateTileZ[iLev][i];
if (hasChunkAt(x, y, z)) {
int id = getTile(x, y, z);
if (Tile::tiles[id] != nullptr && Tile::tiles[id]->isTicking()) {
/*if(id == 2) ++grassTicks;
else if(id == 11) ++lavaTicks;
else ++otherTicks;*/
Tile::tiles[id]->tick(this, x, y, z, random);
}
}
}
// printf("Total ticks - Grass: %d, Lava: %d, Other: %d, Total: %d\n",
// grassTicks, lavaTicks, otherTicks, grassTicks + lavaTicks + otherTicks);
m_updateTileCount[iLev] = 0;
m_updateChunkCount[iLev] = 0;
}
// printf("Total ticks - Grass: %d, Lava: %d, Other: %d, Total: %d\n",
// grassTicks, lavaTicks, otherTicks, grassTicks + lavaTicks + otherTicks);
m_updateTileCount[iLev] = 0;
m_updateChunkCount[iLev] = 0;
LeaveCriticalSection(&m_updateCS[iLev]);
Level::tickTiles();
@ -603,12 +593,13 @@ void ServerLevel::addToTickNextTick(int x, int y, int z, int tileId,
td.delay(tickDelay + levelData->getGameTime());
td.setPriorityTilt(priorityTilt);
}
EnterCriticalSection(&m_tickNextTickCS);
if (tickNextTickSet.find(td) == tickNextTickSet.end()) {
tickNextTickSet.insert(td);
tickNextTickList.insert(td);
{
std::lock_guard<std::mutex> lock(m_tickNextTickCS);
if (tickNextTickSet.find(td) == tickNextTickSet.end()) {
tickNextTickSet.insert(td);
tickNextTickList.insert(td);
}
}
LeaveCriticalSection(&m_tickNextTickCS);
}
MemSect(0);
}
@ -621,12 +612,13 @@ void ServerLevel::forceAddTileTick(int x, int y, int z, int tileId,
if (tileId > 0) {
td.delay(tickDelay + levelData->getGameTime());
}
EnterCriticalSection(&m_tickNextTickCS);
if (tickNextTickSet.find(td) == tickNextTickSet.end()) {
tickNextTickSet.insert(td);
tickNextTickList.insert(td);
{
std::lock_guard<std::mutex> lock(m_tickNextTickCS);
if (tickNextTickSet.find(td) == tickNextTickSet.end()) {
tickNextTickSet.insert(td);
tickNextTickList.insert(td);
}
}
LeaveCriticalSection(&m_tickNextTickCS);
}
void ServerLevel::tickEntities() {
@ -644,7 +636,7 @@ void ServerLevel::tickEntities() {
void ServerLevel::resetEmptyTime() { emptyTime = 0; }
bool ServerLevel::tickPendingTicks(bool force) {
EnterCriticalSection(&m_tickNextTickCS);
std::lock_guard<std::mutex> lock(m_tickNextTickCS);
int count = (int)tickNextTickList.size();
int count2 = (int)tickNextTickSet.size();
if (count != tickNextTickSet.size()) {
@ -687,14 +679,13 @@ bool ServerLevel::tickPendingTicks(bool force) {
int count4 = (int)tickNextTickSet.size();
bool retval = tickNextTickList.size() != 0;
LeaveCriticalSection(&m_tickNextTickCS);
return retval;
}
std::vector<TickNextTickData>* ServerLevel::fetchTicksInChunk(LevelChunk* chunk,
bool remove) {
EnterCriticalSection(&m_tickNextTickCS);
std::lock_guard<std::mutex> lock(m_tickNextTickCS);
std::vector<TickNextTickData>* results = new std::vector<TickNextTickData>;
ChunkPos* pos = chunk->getPos();
@ -749,7 +740,6 @@ std::vector<TickNextTickData>* ServerLevel::fetchTicksInChunk(LevelChunk* chunk,
}
}
LeaveCriticalSection(&m_tickNextTickCS);
return results;
}
@ -1225,13 +1215,12 @@ void ServerLevel::sendParticles(const std::wstring& name, double x, double y,
// 4J Stu - Sometimes we want to update tiles on the server from the main thread
// (eg SignTileEntity when string verify returns)
void ServerLevel::queueSendTileUpdate(int x, int y, int z) {
EnterCriticalSection(&m_csQueueSendTileUpdates);
std::lock_guard<std::mutex> lock(m_csQueueSendTileUpdates);
m_queuedSendTileUpdates.push_back(new Pos(x, y, z));
LeaveCriticalSection(&m_csQueueSendTileUpdates);
}
void ServerLevel::runQueuedSendTileUpdates() {
EnterCriticalSection(&m_csQueueSendTileUpdates);
std::lock_guard<std::mutex> lock(m_csQueueSendTileUpdates);
for (auto it = m_queuedSendTileUpdates.begin();
it != m_queuedSendTileUpdates.end(); ++it) {
Pos* p = *it;
@ -1239,7 +1228,6 @@ void ServerLevel::runQueuedSendTileUpdates() {
delete p;
}
m_queuedSendTileUpdates.clear();
LeaveCriticalSection(&m_csQueueSendTileUpdates);
}
// 4J - added special versions of addEntity and extra processing on entity
@ -1249,53 +1237,48 @@ bool ServerLevel::addEntity(std::shared_ptr<Entity> e) {
if (e->instanceof(eTYPE_ITEMENTITY)) {
// printf("Adding item entity count
//%d\n",m_itemEntities.size());
EnterCriticalSection(&m_limiterCS);
std::lock_guard<std::mutex> lock(m_limiterCS);
if (m_itemEntities.size() >= MAX_ITEM_ENTITIES) {
// printf("Adding - doing remove\n");
removeEntityImmediately(m_itemEntities.front());
}
LeaveCriticalSection(&m_limiterCS);
}
// If its an hanging entity, and we've got to our capacity, delete the
// oldest
else if (e->instanceof(eTYPE_HANGING_ENTITY)) {
// printf("Adding item entity count
//%d\n",m_itemEntities.size());
EnterCriticalSection(&m_limiterCS);
std::lock_guard<std::mutex> lock(m_limiterCS);
if (m_hangingEntities.size() >= MAX_HANGING_ENTITIES) {
// printf("Adding - doing remove\n");
// 4J-PB - refuse to add the entity, since we'll be removing one
// already there, and it may be an item frame with something in it.
LeaveCriticalSection(&m_limiterCS);
return false;
// removeEntityImmediately(m_hangingEntities.front());
}
LeaveCriticalSection(&m_limiterCS);
}
// If its an arrow entity, and we've got to our capacity, delete the oldest
else if (e->instanceof(eTYPE_ARROW)) {
// printf("Adding arrow entity count
//%d\n",m_arrowEntities.size());
EnterCriticalSection(&m_limiterCS);
std::lock_guard<std::mutex> lock(m_limiterCS);
if (m_arrowEntities.size() >= MAX_ARROW_ENTITIES) {
// printf("Adding - doing remove\n");
removeEntityImmediately(m_arrowEntities.front());
}
LeaveCriticalSection(&m_limiterCS);
}
// If its an experience orb entity, and we've got to our capacity, delete
// the oldest
else if (e->instanceof(eTYPE_EXPERIENCEORB)) {
// printf("Adding arrow entity count
//%d\n",m_arrowEntities.size());
EnterCriticalSection(&m_limiterCS);
std::lock_guard<std::mutex> lock(m_limiterCS);
if (m_experienceOrbEntities.size() >= MAX_EXPERIENCEORB_ENTITIES) {
// printf("Adding - doing remove\n");
removeEntityImmediately(m_experienceOrbEntities.front());
}
LeaveCriticalSection(&m_limiterCS);
}
return Level::addEntity(e);
}
@ -1308,21 +1291,17 @@ bool ServerLevel::atEntityLimit(std::shared_ptr<Entity> e) {
bool atLimit = false;
if (e->instanceof(eTYPE_ITEMENTITY)) {
EnterCriticalSection(&m_limiterCS);
std::lock_guard<std::mutex> lock(m_limiterCS);
atLimit = m_itemEntities.size() >= MAX_ITEM_ENTITIES;
LeaveCriticalSection(&m_limiterCS);
} else if (e->instanceof(eTYPE_HANGING_ENTITY)) {
EnterCriticalSection(&m_limiterCS);
std::lock_guard<std::mutex> lock(m_limiterCS);
atLimit = m_hangingEntities.size() >= MAX_HANGING_ENTITIES;
LeaveCriticalSection(&m_limiterCS);
} else if (e->instanceof(eTYPE_ARROW)) {
EnterCriticalSection(&m_limiterCS);
std::lock_guard<std::mutex> lock(m_limiterCS);
atLimit = m_arrowEntities.size() >= MAX_ARROW_ENTITIES;
LeaveCriticalSection(&m_limiterCS);
} else if (e->instanceof(eTYPE_EXPERIENCEORB)) {
EnterCriticalSection(&m_limiterCS);
std::lock_guard<std::mutex> lock(m_limiterCS);
atLimit = m_experienceOrbEntities.size() >= MAX_EXPERIENCEORB_ENTITIES;
LeaveCriticalSection(&m_limiterCS);
}
return atLimit;
@ -1331,37 +1310,31 @@ bool ServerLevel::atEntityLimit(std::shared_ptr<Entity> e) {
// Maintain a cound of primed tnt & falling tiles in this level
void ServerLevel::entityAddedExtra(std::shared_ptr<Entity> e) {
if (e->instanceof(eTYPE_ITEMENTITY)) {
EnterCriticalSection(&m_limiterCS);
std::lock_guard<std::mutex> lock(m_limiterCS);
m_itemEntities.push_back(e);
// printf("entity added: item entity count now
//%d\n",m_itemEntities.size());
LeaveCriticalSection(&m_limiterCS);
} else if (e->instanceof(eTYPE_HANGING_ENTITY)) {
EnterCriticalSection(&m_limiterCS);
std::lock_guard<std::mutex> lock(m_limiterCS);
m_hangingEntities.push_back(e);
// printf("entity added: item entity count now
//%d\n",m_itemEntities.size());
LeaveCriticalSection(&m_limiterCS);
} else if (e->instanceof(eTYPE_ARROW)) {
EnterCriticalSection(&m_limiterCS);
std::lock_guard<std::mutex> lock(m_limiterCS);
m_arrowEntities.push_back(e);
// printf("entity added: arrow entity count now
//%d\n",m_arrowEntities.size());
LeaveCriticalSection(&m_limiterCS);
} else if (e->instanceof(eTYPE_EXPERIENCEORB)) {
EnterCriticalSection(&m_limiterCS);
std::lock_guard<std::mutex> lock(m_limiterCS);
m_experienceOrbEntities.push_back(e);
// printf("entity added: experience orb entity count now
//%d\n",m_arrowEntities.size());
LeaveCriticalSection(&m_limiterCS);
} else if (e->instanceof(eTYPE_PRIMEDTNT)) {
EnterCriticalSection(&m_limiterCS);
std::lock_guard<std::mutex> lock(m_limiterCS);
m_primedTntCount++;
LeaveCriticalSection(&m_limiterCS);
} else if (e->instanceof(eTYPE_FALLINGTILE)) {
EnterCriticalSection(&m_limiterCS);
std::lock_guard<std::mutex> lock(m_limiterCS);
m_fallingTileCount++;
LeaveCriticalSection(&m_limiterCS);
}
}
@ -1369,7 +1342,7 @@ void ServerLevel::entityAddedExtra(std::shared_ptr<Entity> e) {
// item entities from our list
void ServerLevel::entityRemovedExtra(std::shared_ptr<Entity> e) {
if (e->instanceof(eTYPE_ITEMENTITY)) {
EnterCriticalSection(&m_limiterCS);
std::lock_guard<std::mutex> lock(m_limiterCS);
// printf("entity removed: item entity count
//%d\n",m_itemEntities.size());
auto it = find(m_itemEntities.begin(), m_itemEntities.end(), e);
@ -1379,9 +1352,8 @@ void ServerLevel::entityRemovedExtra(std::shared_ptr<Entity> e) {
}
// printf("entity removed: item entity count now
//%d\n",m_itemEntities.size());
LeaveCriticalSection(&m_limiterCS);
} else if (e->instanceof(eTYPE_HANGING_ENTITY)) {
EnterCriticalSection(&m_limiterCS);
std::lock_guard<std::mutex> lock(m_limiterCS);
// printf("entity removed: item entity count
//%d\n",m_itemEntities.size());
auto it =
@ -1392,9 +1364,8 @@ void ServerLevel::entityRemovedExtra(std::shared_ptr<Entity> e) {
}
// printf("entity removed: item entity count now
//%d\n",m_itemEntities.size());
LeaveCriticalSection(&m_limiterCS);
} else if (e->instanceof(eTYPE_ARROW)) {
EnterCriticalSection(&m_limiterCS);
std::lock_guard<std::mutex> lock(m_limiterCS);
// printf("entity removed: arrow entity count
//%d\n",m_arrowEntities.size());
auto it = find(m_arrowEntities.begin(), m_arrowEntities.end(), e);
@ -1404,9 +1375,8 @@ void ServerLevel::entityRemovedExtra(std::shared_ptr<Entity> e) {
}
// printf("entity removed: arrow entity count now
//%d\n",m_arrowEntities.size());
LeaveCriticalSection(&m_limiterCS);
} else if (e->instanceof(eTYPE_EXPERIENCEORB)) {
EnterCriticalSection(&m_limiterCS);
std::lock_guard<std::mutex> lock(m_limiterCS);
// printf("entity removed: experience orb entity count
//%d\n",m_arrowEntities.size());
auto it = find(m_experienceOrbEntities.begin(),
@ -1417,29 +1387,24 @@ void ServerLevel::entityRemovedExtra(std::shared_ptr<Entity> e) {
}
// printf("entity removed: experience orb entity count now
//%d\n",m_arrowEntities.size());
LeaveCriticalSection(&m_limiterCS);
} else if (e->instanceof(eTYPE_PRIMEDTNT)) {
EnterCriticalSection(&m_limiterCS);
std::lock_guard<std::mutex> lock(m_limiterCS);
m_primedTntCount--;
LeaveCriticalSection(&m_limiterCS);
} else if (e->instanceof(eTYPE_FALLINGTILE)) {
EnterCriticalSection(&m_limiterCS);
std::lock_guard<std::mutex> lock(m_limiterCS);
m_fallingTileCount--;
LeaveCriticalSection(&m_limiterCS);
}
}
bool ServerLevel::newPrimedTntAllowed() {
EnterCriticalSection(&m_limiterCS);
std::lock_guard<std::mutex> lock(m_limiterCS);
bool retval = m_primedTntCount < MAX_PRIMED_TNT;
LeaveCriticalSection(&m_limiterCS);
return retval;
}
bool ServerLevel::newFallingTileAllowed() {
EnterCriticalSection(&m_limiterCS);
std::lock_guard<std::mutex> lock(m_limiterCS);
bool retval = m_fallingTileCount < MAX_FALLING_TILE;
LeaveCriticalSection(&m_limiterCS);
return retval;
}
@ -1458,7 +1423,7 @@ int ServerLevel::runUpdate(void* lpParam) {
int grassTicks = 0;
int lavaTicks = 0;
for (unsigned int iLev = 0; iLev < 3; ++iLev) {
EnterCriticalSection(&m_updateCS[iLev]);
std::lock_guard<std::mutex> lock(m_updateCS[iLev]);
for (int i = 0; i < m_updateChunkCount[iLev]; i++) {
// 4J - some of these tile ticks will check things in
// neighbouring tiles, causing chunks to load/create that aren't
@ -1548,7 +1513,6 @@ int ServerLevel::runUpdate(void* lpParam) {
}
}
}
LeaveCriticalSection(&m_updateCS[iLev]);
}
PIXEndNamedEvent();
}

View file

@ -1,4 +1,5 @@
#pragma once
#include <mutex>
#include "../../Minecraft.World/Headers/net.minecraft.world.level.h"
#include "../../Minecraft.World/Util/JavaIntHash.h"
class ServerChunkCache;
@ -16,7 +17,7 @@ private:
EntityTracker* tracker;
PlayerChunkMap* chunkMap;
CRITICAL_SECTION m_tickNextTickCS; // 4J added
std::mutex m_tickNextTickCS; // 4J added
std::set<TickNextTickData, TickNextTickDataKeyCompare>
tickNextTickList; // 4J Was TreeSet
std::unordered_set<TickNextTickData, TickNextTickDataKeyHash,
@ -24,7 +25,7 @@ private:
tickNextTickSet; // 4J Was HashSet
std::vector<Pos*> m_queuedSendTileUpdates; // 4J added
CRITICAL_SECTION m_csQueueSendTileUpdates;
std::mutex m_csQueueSendTileUpdates;
protected:
int saveInterval;
@ -177,7 +178,7 @@ public:
int m_primedTntCount;
int m_fallingTileCount;
CRITICAL_SECTION m_limiterCS;
std::mutex m_limiterCS;
std::list<std::shared_ptr<Entity> > m_itemEntities;
std::list<std::shared_ptr<Entity> > m_hangingEntities;
std::list<std::shared_ptr<Entity> > m_arrowEntities;
@ -211,7 +212,7 @@ public:
static int m_randValue[3];
static C4JThread::EventArray* m_updateTrigger;
static CRITICAL_SECTION m_updateCS[3];
static std::mutex m_updateCS[3];
static C4JThread* m_updateThread;
static int runUpdate(void* lpParam);

View file

@ -121,8 +121,6 @@ Minecraft::Minecraft(Component* mouseComponent, Canvas* parent,
rightClickDelay = 0;
// 4J Stu Added
InitializeCriticalSection(&ProgressRenderer::s_progress);
InitializeCriticalSection(&m_setLevelCS);
// m_hPlayerRespawned = CreateEvent(nullptr, false, false, nullptr);
progressRenderer = nullptr;
@ -987,7 +985,7 @@ void Minecraft::run_middle() {
}
#endif
EnterCriticalSection(&m_setLevelCS);
{ std::lock_guard<std::mutex> lock(m_setLevelCS);
if (running) {
if (reloadTextures) {
@ -1734,7 +1732,7 @@ void Minecraft::run_middle() {
}
*/
}
LeaveCriticalSection(&m_setLevelCS);
} // lock_guard scope
}
void Minecraft::run_end() { destroy(); }
@ -3670,7 +3668,7 @@ void Minecraft::setLevel(MultiPlayerLevel* level, int message /*=-1*/,
std::shared_ptr<Player> forceInsertPlayer /*=nullptr*/,
bool doForceStatsSave /*=true*/,
bool bPrimaryPlayerSignedOut /*=false*/) {
EnterCriticalSection(&m_setLevelCS);
std::lock_guard<std::mutex> lock(m_setLevelCS);
bool playerAdded = false;
this->cameraTargetPlayer = nullptr;
@ -3842,7 +3840,6 @@ void Minecraft::setLevel(MultiPlayerLevel* level, int message /*=-1*/,
// System.gc(); // 4J - removed
// 4J removed
// this->lastTickTime = 0;
LeaveCriticalSection(&m_setLevelCS);
}
void Minecraft::prepareLevel(int title) {

View file

@ -1,4 +1,5 @@
#pragma once
#include <mutex>
class Timer;
class MultiPlayerLevel;
class LevelRenderer;
@ -347,7 +348,7 @@ public:
// 4J Stu
void forceStatsSave(int idx);
CRITICAL_SECTION m_setLevelCS;
std::mutex m_setLevelCS;
private:
// A bit field that store whether a particular quadrant is in the full

View file

@ -243,38 +243,39 @@ int MinecraftServer::runPostUpdate(void* lpParam) {
// Update lights for both levels until we are signalled to terminate
do {
EnterCriticalSection(&server->m_postProcessCS);
if (server->m_postProcessRequests.size()) {
MinecraftServer::postProcessRequest request =
server->m_postProcessRequests.back();
server->m_postProcessRequests.pop_back();
LeaveCriticalSection(&server->m_postProcessCS);
static int count = 0;
PIXBeginNamedEvent(0, "Post processing %d ", (count++) % 8);
request.chunkSource->postProcess(request.chunkSource, request.x,
request.z);
PIXEndNamedEvent();
} else {
LeaveCriticalSection(&server->m_postProcessCS);
{
std::unique_lock<std::mutex> lock(server->m_postProcessCS);
if (server->m_postProcessRequests.size()) {
MinecraftServer::postProcessRequest request =
server->m_postProcessRequests.back();
server->m_postProcessRequests.pop_back();
lock.unlock();
static int count = 0;
PIXBeginNamedEvent(0, "Post processing %d ", (count++) % 8);
request.chunkSource->postProcess(request.chunkSource, request.x,
request.z);
PIXEndNamedEvent();
}
}
std::this_thread::sleep_for(std::chrono::milliseconds(1));
} while (!server->m_postUpdateTerminate &&
ShutdownManager::ShouldRun(ShutdownManager::ePostProcessThread));
// #ifndef 0
// One final pass through updates to make sure we're done
EnterCriticalSection(&server->m_postProcessCS);
int maxRequests = server->m_postProcessRequests.size();
while (server->m_postProcessRequests.size() &&
ShutdownManager::ShouldRun(ShutdownManager::ePostProcessThread)) {
MinecraftServer::postProcessRequest request =
server->m_postProcessRequests.back();
server->m_postProcessRequests.pop_back();
LeaveCriticalSection(&server->m_postProcessCS);
request.chunkSource->postProcess(request.chunkSource, request.x,
request.z);
EnterCriticalSection(&server->m_postProcessCS);
{
std::unique_lock<std::mutex> lock(server->m_postProcessCS);
int maxRequests = server->m_postProcessRequests.size();
while (server->m_postProcessRequests.size() &&
ShutdownManager::ShouldRun(ShutdownManager::ePostProcessThread)) {
MinecraftServer::postProcessRequest request =
server->m_postProcessRequests.back();
server->m_postProcessRequests.pop_back();
lock.unlock();
request.chunkSource->postProcess(request.chunkSource, request.x,
request.z);
lock.lock();
}
}
LeaveCriticalSection(&server->m_postProcessCS);
// #endif //0
Tile::ReleaseThreadStorage();
Level::destroyLightingCache();
@ -286,26 +287,28 @@ int MinecraftServer::runPostUpdate(void* lpParam) {
void MinecraftServer::addPostProcessRequest(ChunkSource* chunkSource, int x,
int z) {
EnterCriticalSection(&m_postProcessCS);
{ std::lock_guard<std::mutex> lock(m_postProcessCS);
m_postProcessRequests.push_back(
MinecraftServer::postProcessRequest(x, z, chunkSource));
LeaveCriticalSection(&m_postProcessCS);
}
}
void MinecraftServer::postProcessTerminate(ProgressRenderer* mcprogress) {
std::uint32_t status = 0;
size_t postProcessItemCount = 0;
size_t postProcessItemRemaining = 0;
EnterCriticalSection(&server->m_postProcessCS);
size_t postProcessItemCount = server->m_postProcessRequests.size();
LeaveCriticalSection(&server->m_postProcessCS);
{ std::lock_guard<std::mutex> lock(server->m_postProcessCS);
postProcessItemCount = server->m_postProcessRequests.size();
}
do {
status = m_postUpdateThread->WaitForCompletion(50);
if (status == WAIT_TIMEOUT) {
EnterCriticalSection(&server->m_postProcessCS);
size_t postProcessItemRemaining =
{ std::lock_guard<std::mutex> lock(server->m_postProcessCS);
postProcessItemRemaining =
server->m_postProcessRequests.size();
LeaveCriticalSection(&server->m_postProcessCS);
}
if (postProcessItemCount) {
mcprogress->progressStagePercentage(
@ -319,7 +322,6 @@ void MinecraftServer::postProcessTerminate(ProgressRenderer* mcprogress) {
} while (status == WAIT_TIMEOUT);
delete m_postUpdateThread;
m_postUpdateThread = nullptr;
DeleteCriticalSection(&m_postProcessCS);
}
bool MinecraftServer::loadLevel(LevelStorageSource* storageSource,
@ -481,7 +483,6 @@ bool MinecraftServer::loadLevel(LevelStorageSource* storageSource,
if (s_bServerHalted || !g_NetworkManager.IsInSession()) return false;
// 4J - Make a new thread to do post processing
InitializeCriticalSection(&m_postProcessCS);
// 4J-PB - fix for 108310 - TCR #001 BAS Game Stability: TU12: Code:
// Compliance: Crash after creating world on "journey" seed. Stack gets very

View file

@ -1,5 +1,6 @@
#pragma once
#include <cstdint>
#include <mutex>
#include "Input/ConsoleInputSource.h"
#include "../Minecraft.World/Util/ArrayWithLength.h"
@ -247,7 +248,7 @@ private:
: x(x), z(z), chunkSource(chunkSource) {}
};
std::vector<postProcessRequest> m_postProcessRequests;
CRITICAL_SECTION m_postProcessCS;
std::mutex m_postProcessCS;
public:
void addPostProcessRequest(ChunkSource* chunkSource, int x, int z);

View file

@ -89,7 +89,6 @@ MultiPlayerChunkCache::MultiPlayerChunkCache(Level* level) {
this->cache = new LevelChunk*[XZSIZE * XZSIZE];
memset(this->cache, 0, XZSIZE * XZSIZE * sizeof(LevelChunk*));
InitializeCriticalSectionAndSpinCount(&m_csLoadCreate, 4000);
}
MultiPlayerChunkCache::~MultiPlayerChunkCache() {
@ -100,8 +99,6 @@ MultiPlayerChunkCache::~MultiPlayerChunkCache() {
auto itEnd = loadedChunkList.end();
for (auto it = loadedChunkList.begin(); it != itEnd; it++) delete *it;
DeleteCriticalSection(&m_csLoadCreate);
}
bool MultiPlayerChunkCache::hasChunk(int x, int z) {
@ -158,7 +155,7 @@ LevelChunk* MultiPlayerChunkCache::create(int x, int z) {
LevelChunk* lastChunk = chunk;
if (chunk == nullptr) {
EnterCriticalSection(&m_csLoadCreate);
{ std::unique_lock<std::mutex> lock(m_csLoadCreate);
// LevelChunk *chunk;
if (g_NetworkManager.IsHost()) // force here to disable sharing of data
@ -199,8 +196,7 @@ LevelChunk* MultiPlayerChunkCache::create(int x, int z) {
}
chunk->loaded = true;
LeaveCriticalSection(&m_csLoadCreate);
}
#if (defined _WIN64 || defined __LP64__)
if (InterlockedCompareExchangeRelease64(
@ -220,9 +216,9 @@ LevelChunk* MultiPlayerChunkCache::create(int x, int z) {
}
// Successfully updated the cache
EnterCriticalSection(&m_csLoadCreate);
{ std::lock_guard<std::mutex> lock(m_csLoadCreate);
loadedChunkList.push_back(chunk);
LeaveCriticalSection(&m_csLoadCreate);
}
} else {
// Something else must have updated the cache. Return that chunk and
// discard this one. This really shouldn't be happening in
@ -281,9 +277,10 @@ void MultiPlayerChunkCache::recreateLogicStructuresForChunk(int chunkX,
int chunkZ) {}
std::wstring MultiPlayerChunkCache::gatherStats() {
EnterCriticalSection(&m_csLoadCreate);
int size = (int)loadedChunkList.size();
LeaveCriticalSection(&m_csLoadCreate);
int size;
{ std::lock_guard<std::mutex> lock(m_csLoadCreate);
size = (int)loadedChunkList.size();
}
return L"MultiplayerChunkCache: " + _toString<int>(size);
}

View file

@ -1,4 +1,5 @@
#pragma once
#include <mutex>
#include "../../Minecraft.World/Headers/net.minecraft.world.level.h"
#include "../../Minecraft.World/Headers/net.minecraft.world.level.chunk.h"
#include "../../Minecraft.World/Level/RandomLevelSource.h"
@ -18,7 +19,7 @@ private:
LevelChunk** cache;
// 4J - added for multithreaded support
CRITICAL_SECTION m_csLoadCreate;
std::mutex m_csLoadCreate;
// 4J - size of cache is defined by size of one side - must be even
int XZSIZE;
int XZOFFSET;

View file

@ -57,8 +57,6 @@ PlayerConnection::PlayerConnection(MinecraftServer* server,
this->player = player;
// player->connection = this; // 4J - moved out as we can't
// assign in a ctor
InitializeCriticalSection(&done_cs);
m_bCloseOnTick = false;
m_bWasKicked = false;
@ -73,7 +71,6 @@ PlayerConnection::PlayerConnection(MinecraftServer* server,
PlayerConnection::~PlayerConnection() {
delete connection;
DeleteCriticalSection(&done_cs);
}
void PlayerConnection::tick() {
@ -106,9 +103,8 @@ void PlayerConnection::tick() {
}
void PlayerConnection::disconnect(DisconnectPacket::eDisconnectReason reason) {
EnterCriticalSection(&done_cs);
std::lock_guard<std::mutex> lock(done_cs);
if (done) {
LeaveCriticalSection(&done_cs);
return;
}
@ -135,7 +131,6 @@ void PlayerConnection::disconnect(DisconnectPacket::eDisconnectReason reason) {
server->getPlayers()->remove(player);
done = true;
LeaveCriticalSection(&done_cs);
}
void PlayerConnection::handlePlayerInput(
@ -555,7 +550,7 @@ void PlayerConnection::handleUseItem(std::shared_ptr<UseItemPacket> packet) {
void PlayerConnection::onDisconnect(DisconnectPacket::eDisconnectReason reason,
void* reasonObjects) {
EnterCriticalSection(&done_cs);
std::lock_guard<std::mutex> lock(done_cs);
if (done) return;
// logger.info(player.name + " lost connection: " + reason);
// 4J-PB - removed, since it needs to be localised in the language the
@ -572,7 +567,6 @@ void PlayerConnection::onDisconnect(DisconnectPacket::eDisconnectReason reason,
}
server->getPlayers()->remove(player);
done = true;
LeaveCriticalSection(&done_cs);
}
void PlayerConnection::onUnhandledPacket(std::shared_ptr<Packet> packet) {

View file

@ -1,4 +1,5 @@
#pragma once
#include <mutex>
#include "../Input/ConsoleInputSource.h"
#include "../../Minecraft.World/Network/Packets/PacketListener.h"
#include "../../Minecraft.World/Util/JavaIntHash.h"
@ -14,7 +15,7 @@ class PlayerConnection : public PacketListener, public ConsoleInputSource {
public:
Connection* connection;
bool done;
CRITICAL_SECTION done_cs;
std::mutex done_cs;
// 4J Stu - Added this so that we can manage UGC privileges
PlayerUID m_offlineXUID, m_onlineXUID;

View file

@ -49,8 +49,6 @@ PlayerList::PlayerList(MinecraftServer* server) {
maxPlayers = server->settings->getInt(L"max-players", 20);
doWhiteList = false;
InitializeCriticalSection(&m_kickPlayersCS);
InitializeCriticalSection(&m_closePlayersCS);
}
PlayerList::~PlayerList() {
@ -62,8 +60,6 @@ PlayerList::~PlayerList() {
(*it)->gameMode = nullptr;
}
DeleteCriticalSection(&m_kickPlayersCS);
DeleteCriticalSection(&m_closePlayersCS);
}
void PlayerList::placeNewPlayer(Connection* connection,
@ -997,7 +993,7 @@ void PlayerList::tick() {
}
}
EnterCriticalSection(&m_closePlayersCS);
{ std::lock_guard<std::mutex> lock(m_closePlayersCS);
while (!m_smallIdsToClose.empty()) {
std::uint8_t smallId = m_smallIdsToClose.front();
m_smallIdsToClose.pop_front();
@ -1023,9 +1019,9 @@ void PlayerList::tick() {
DisconnectPacket::eDisconnect_Closed);
}
}
LeaveCriticalSection(&m_closePlayersCS);
}
EnterCriticalSection(&m_kickPlayersCS);
{ std::lock_guard<std::mutex> lock(m_kickPlayersCS);
while (!m_smallIdsToKick.empty()) {
std::uint8_t smallId = m_smallIdsToKick.front();
m_smallIdsToKick.pop_front();
@ -1063,7 +1059,7 @@ void PlayerList::tick() {
}
}
}
LeaveCriticalSection(&m_kickPlayersCS);
}
// Check our receiving players, and if they are dead see if we can replace
// them
@ -1628,15 +1624,15 @@ bool PlayerList::canReceiveAllPackets(std::shared_ptr<ServerPlayer> player) {
}
void PlayerList::kickPlayerByShortId(std::uint8_t networkSmallId) {
EnterCriticalSection(&m_kickPlayersCS);
{ std::lock_guard<std::mutex> lock(m_kickPlayersCS);
m_smallIdsToKick.push_back(networkSmallId);
LeaveCriticalSection(&m_kickPlayersCS);
}
}
void PlayerList::closePlayerConnectionBySmallId(std::uint8_t networkSmallId) {
EnterCriticalSection(&m_closePlayersCS);
{ std::lock_guard<std::mutex> lock(m_closePlayersCS);
m_smallIdsToClose.push_back(networkSmallId);
LeaveCriticalSection(&m_closePlayersCS);
}
}
bool PlayerList::isXuidBanned(PlayerUID xuid) {

View file

@ -1,6 +1,7 @@
#pragma once
#include <cstdint>
#include <deque>
#include <mutex>
#include "../../Minecraft.World/Util/ArrayWithLength.h"
class ServerPlayer;
@ -31,9 +32,9 @@ private:
// 4J Added
std::vector<PlayerUID> m_bannedXuids;
std::deque<std::uint8_t> m_smallIdsToKick;
CRITICAL_SECTION m_kickPlayersCS;
std::mutex m_kickPlayersCS;
std::deque<std::uint8_t> m_smallIdsToClose;
CRITICAL_SECTION m_closePlayersCS;
std::mutex m_closePlayersCS;
/* 4J - removed
Set<String> bans = new HashSet<String>();
Set<String> ipBans = new HashSet<String>();

View file

@ -39,7 +39,6 @@ ServerChunkCache::ServerChunkCache(ServerLevel* level, ChunkStorage* storage,
memset(m_unloadedCache, 0, XZSIZE * XZSIZE * sizeof(LevelChunk*));
#endif
InitializeCriticalSectionAndSpinCount(&m_csLoadCreate, 4000);
}
// 4J-PB added
@ -58,7 +57,6 @@ ServerChunkCache::~ServerChunkCache() {
auto itEnd = m_loadedChunkList.end();
for (auto it = m_loadedChunkList.begin(); it != itEnd; it++) delete *it;
DeleteCriticalSection(&m_csLoadCreate);
}
bool ServerChunkCache::hasChunk(int x, int z) {
@ -146,7 +144,7 @@ LevelChunk* ServerChunkCache::create(
LevelChunk* lastChunk = chunk;
if ((chunk == nullptr) || (chunk->x != x) || (chunk->z != z)) {
EnterCriticalSection(&m_csLoadCreate);
{ std::lock_guard<std::mutex> lock(m_csLoadCreate);
chunk = load(x, z);
if (chunk == nullptr) {
if (source == nullptr) {
@ -158,8 +156,7 @@ LevelChunk* ServerChunkCache::create(
if (chunk != nullptr) {
chunk->load();
}
LeaveCriticalSection(&m_csLoadCreate);
}
#if defined(_WIN64) || defined(__LP64__)
if (InterlockedCompareExchangeRelease64(
@ -172,7 +169,7 @@ LevelChunk* ServerChunkCache::create(
#endif
{
// Successfully updated the cache
EnterCriticalSection(&m_csLoadCreate);
std::lock_guard<std::mutex> lock(m_csLoadCreate);
// 4J - added - this will run a recalcHeightmap if source is a
// randomlevelsource, which has been split out from source::getChunk
// so that we are doing it after the chunk has been added to the
@ -269,7 +266,6 @@ LevelChunk* ServerChunkCache::create(
hasChunk(x, z - 1) && hasChunk(x, z + 1))
chunk->checkChests(this, x, z);
LeaveCriticalSection(&m_csLoadCreate);
} else {
// Something else must have updated the cache. Return that chunk and
// discard this one
@ -653,12 +649,12 @@ bool ServerChunkCache::saveAllEntities() {
PIXBeginNamedEvent(0, "Save all entities");
PIXBeginNamedEvent(0, "saving to NBT");
EnterCriticalSection(&m_csLoadCreate);
{ std::lock_guard<std::mutex> lock(m_csLoadCreate);
for (auto it = m_loadedChunkList.begin(); it != m_loadedChunkList.end();
++it) {
storage->saveEntities(level, *it);
}
LeaveCriticalSection(&m_csLoadCreate);
}
PIXEndNamedEvent();
PIXBeginNamedEvent(0, "Flushing");
@ -670,7 +666,7 @@ bool ServerChunkCache::saveAllEntities() {
}
bool ServerChunkCache::save(bool force, ProgressListener* progressListener) {
EnterCriticalSection(&m_csLoadCreate);
std::lock_guard<std::mutex> lock(m_csLoadCreate);
int saves = 0;
// 4J - added this to support progressListner
@ -701,7 +697,6 @@ bool ServerChunkCache::save(bool force, ProgressListener* progressListener) {
save(chunk);
chunk->setUnsaved(false);
if (++saves == MAX_SAVES && !force) {
LeaveCriticalSection(&m_csLoadCreate);
return false;
}
@ -751,7 +746,6 @@ bool ServerChunkCache::save(bool force, ProgressListener* progressListener) {
save(chunk);
chunk->setUnsaved(false);
if (++saves == MAX_SAVES && !force) {
LeaveCriticalSection(&m_csLoadCreate);
return false;
}
@ -776,13 +770,11 @@ bool ServerChunkCache::save(bool force, ProgressListener* progressListener) {
if (force) {
if (storage == nullptr) {
LeaveCriticalSection(&m_csLoadCreate);
return true;
}
storage->flush();
}
LeaveCriticalSection(&m_csLoadCreate);
return !maxSavesReached;
}

View file

@ -1,4 +1,5 @@
#pragma once
#include <mutex>
#include "../../Minecraft.World/Headers/net.minecraft.world.level.h"
#include "../../Minecraft.World/IO/Files/File.h"
#include "../../Minecraft.World/Headers/net.minecraft.world.level.storage.h"
@ -30,7 +31,7 @@ private:
#endif
// 4J - added for multithreaded support
CRITICAL_SECTION m_csLoadCreate;
std::mutex m_csLoadCreate;
// 4J - size of cache is defined by size of one side - must be even
int XZSIZE;
int XZOFFSET;

View file

@ -12,12 +12,11 @@
ServerConnection::ServerConnection(MinecraftServer* server) {
// 4J - added initialiser
connectionCounter = 0;
InitializeCriticalSection(&pending_cs);
this->server = server;
}
ServerConnection::~ServerConnection() { DeleteCriticalSection(&pending_cs); }
ServerConnection::~ServerConnection() {}
// 4J - added to handle incoming connections, to replace thread that original
// used to have
@ -35,18 +34,18 @@ void ServerConnection::addPlayerConnection(
}
void ServerConnection::handleConnection(std::shared_ptr<PendingConnection> uc) {
EnterCriticalSection(&pending_cs);
{ std::lock_guard<std::mutex> lock(pending_cs);
pending.push_back(uc);
LeaveCriticalSection(&pending_cs);
}
}
void ServerConnection::stop() {
EnterCriticalSection(&pending_cs);
{ std::lock_guard<std::mutex> lock(pending_cs);
for (unsigned int i = 0; i < pending.size(); i++) {
std::shared_ptr<PendingConnection> uc = pending[i];
uc->connection->close(DisconnectPacket::eDisconnect_Closed);
}
LeaveCriticalSection(&pending_cs);
}
for (unsigned int i = 0; i < players.size(); i++) {
std::shared_ptr<PlayerConnection> player = players[i];
@ -58,9 +57,10 @@ void ServerConnection::tick() {
{
// MGH - changed this so that the the CS lock doesn't cover the tick
// (was causing a lockup when 2 players tried to join)
EnterCriticalSection(&pending_cs);
std::vector<std::shared_ptr<PendingConnection> > tempPending = pending;
LeaveCriticalSection(&pending_cs);
std::vector<std::shared_ptr<PendingConnection> > tempPending;
{ std::lock_guard<std::mutex> lock(pending_cs);
tempPending = pending;
}
for (unsigned int i = 0; i < tempPending.size(); i++) {
std::shared_ptr<PendingConnection> uc = tempPending[i];
@ -76,13 +76,13 @@ void ServerConnection::tick() {
}
// now remove from the pending list
EnterCriticalSection(&pending_cs);
{ std::lock_guard<std::mutex> lock(pending_cs);
for (unsigned int i = 0; i < pending.size(); i++)
if (pending[i]->done) {
pending.erase(pending.begin() + i);
i--;
}
LeaveCriticalSection(&pending_cs);
}
for (unsigned int i = 0; i < players.size(); i++) {
std::shared_ptr<PlayerConnection> player = players[i];

View file

@ -1,4 +1,5 @@
#pragma once
#include <mutex>
class PendingConnection;
class PlayerConnection;
class MinecraftServer;
@ -18,7 +19,7 @@ private:
int connectionCounter;
private:
CRITICAL_SECTION pending_cs; // 4J added
std::mutex pending_cs; // 4J added
std::vector<std::shared_ptr<PendingConnection> > pending;
std::vector<std::shared_ptr<PlayerConnection> > players;

View file

@ -28,7 +28,6 @@ class C4JMemoryPoolFixed : public C4JMemoryPool
uchar* m_memStart; // Beginning of memory pool
uchar* m_memEnd; // End of memory pool
uchar* m_next; // Num of next free block
// CRITICAL_SECTION m_CS;
public:
C4JMemoryPoolFixed()
{
@ -59,7 +58,6 @@ public:
m_numOfBlocks ];
m_memEnd = m_memStart + (m_sizeOfEachBlock * m_numOfBlocks);
m_next = m_memStart;
// InitializeCriticalSection(&m_CS);
}
void DestroyPool()
@ -82,7 +80,6 @@ public:
{
if(size > m_sizeOfEachBlock)
return ::malloc(size);
// EnterCriticalSection(&m_CS);
if (m_numInitialized < m_numOfBlocks )
{
uint* p = (uint*)AddrFromIndex( m_numInitialized );
@ -103,7 +100,6 @@ public:
m_next = nullptr;
}
}
// LeaveCriticalSection(&m_CS);
return ret;
}
@ -114,7 +110,6 @@ public:
::free(ptr);
return;
}
// EnterCriticalSection(&m_CS);
if (m_next != nullptr)
{
(*(uint*)ptr) = IndexFromAddr( m_next );
@ -126,7 +121,6 @@ public:
m_next = (uchar*)ptr;
}
++m_numFreeBlocks;
// LeaveCriticalSection(&m_CS);
}
}; // End pool class

View file

@ -178,17 +178,8 @@ CMinecraftApp::CMinecraftApp() {
m_iDLCOfferC = 0;
m_bAllDLCContentRetrieved = true;
InitializeCriticalSection(&csDLCDownloadQueue);
m_bAllTMSContentRetrieved = true;
m_bTickTMSDLCFiles = true;
InitializeCriticalSection(&csTMSPPDownloadQueue);
InitializeCriticalSection(&csAdditionalModelParts);
InitializeCriticalSection(&csAdditionalSkinBoxes);
InitializeCriticalSection(&csAnimOverrideBitmask);
InitializeCriticalSection(&csMemFilesLock);
InitializeCriticalSection(&csMemTPDLock);
InitializeCriticalSection(&m_saveNotificationCriticalSection);
m_saveNotificationDepth = 0;
m_dwRequiredTexturePackID = 0;
@ -4579,7 +4570,7 @@ bool CMinecraftApp::isXuidDeadmau5(PlayerUID xuid) {
void CMinecraftApp::AddMemoryTextureFile(const std::wstring& wName,
std::uint8_t* pbData,
unsigned int byteCount) {
EnterCriticalSection(&csMemFilesLock);
std::lock_guard<std::mutex> lock(csMemFilesLock);
// check it's not already in
PMEMDATA pData = nullptr;
auto it = m_MEM_Files.find(wName);
@ -4599,7 +4590,6 @@ void CMinecraftApp::AddMemoryTextureFile(const std::wstring& wName,
}
++pData->ucRefCount;
LeaveCriticalSection(&csMemFilesLock);
return;
}
@ -4618,12 +4608,10 @@ void CMinecraftApp::AddMemoryTextureFile(const std::wstring& wName,
// use the xuid to access the skin data
m_MEM_Files[wName] = pData;
LeaveCriticalSection(&csMemFilesLock);
}
void CMinecraftApp::RemoveMemoryTextureFile(const std::wstring& wName) {
EnterCriticalSection(&csMemFilesLock);
std::lock_guard<std::mutex> lock(csMemFilesLock);
auto it = m_MEM_Files.find(wName);
if (it != m_MEM_Files.end()) {
@ -4642,17 +4630,16 @@ void CMinecraftApp::RemoveMemoryTextureFile(const std::wstring& wName) {
m_MEM_Files.erase(wName);
}
}
LeaveCriticalSection(&csMemFilesLock);
}
bool CMinecraftApp::DefaultCapeExists() {
std::wstring wTex = L"Special_Cape.png";
bool val = false;
EnterCriticalSection(&csMemFilesLock);
{ std::lock_guard<std::mutex> lock(csMemFilesLock);
auto it = m_MEM_Files.find(wTex);
if (it != m_MEM_Files.end()) val = true;
LeaveCriticalSection(&csMemFilesLock);
}
return val;
}
@ -4660,10 +4647,10 @@ bool CMinecraftApp::DefaultCapeExists() {
bool CMinecraftApp::IsFileInMemoryTextures(const std::wstring& wName) {
bool val = false;
EnterCriticalSection(&csMemFilesLock);
{ std::lock_guard<std::mutex> lock(csMemFilesLock);
auto it = m_MEM_Files.find(wName);
if (it != m_MEM_Files.end()) val = true;
LeaveCriticalSection(&csMemFilesLock);
}
return val;
}
@ -4671,19 +4658,18 @@ bool CMinecraftApp::IsFileInMemoryTextures(const std::wstring& wName) {
void CMinecraftApp::GetMemFileDetails(const std::wstring& wName,
std::uint8_t** ppbData,
unsigned int* pByteCount) {
EnterCriticalSection(&csMemFilesLock);
std::lock_guard<std::mutex> lock(csMemFilesLock);
auto it = m_MEM_Files.find(wName);
if (it != m_MEM_Files.end()) {
PMEMDATA pData = (*it).second;
*ppbData = pData->pbData;
*pByteCount = pData->byteCount;
}
LeaveCriticalSection(&csMemFilesLock);
}
void CMinecraftApp::AddMemoryTPDFile(int iConfig, std::uint8_t* pbData,
unsigned int byteCount) {
EnterCriticalSection(&csMemTPDLock);
std::lock_guard<std::mutex> lock(csMemTPDLock);
// check it's not already in
PMEMDATA pData = nullptr;
auto it = m_MEM_TPD.find(iConfig);
@ -4695,12 +4681,10 @@ void CMinecraftApp::AddMemoryTPDFile(int iConfig, std::uint8_t* pbData,
m_MEM_TPD[iConfig] = pData;
}
LeaveCriticalSection(&csMemTPDLock);
}
void CMinecraftApp::RemoveMemoryTPDFile(int iConfig) {
EnterCriticalSection(&csMemTPDLock);
std::lock_guard<std::mutex> lock(csMemTPDLock);
// check it's not already in
PMEMDATA pData = nullptr;
auto it = m_MEM_TPD.find(iConfig);
@ -4709,8 +4693,6 @@ void CMinecraftApp::RemoveMemoryTPDFile(int iConfig) {
delete pData;
m_MEM_TPD.erase(iConfig);
}
LeaveCriticalSection(&csMemTPDLock);
}
#if defined(_WINDOWS64)
@ -4719,24 +4701,23 @@ int CMinecraftApp::GetTPConfigVal(wchar_t* pwchDataFile) { return -1; }
bool CMinecraftApp::IsFileInTPD(int iConfig) {
bool val = false;
EnterCriticalSection(&csMemTPDLock);
{ std::lock_guard<std::mutex> lock(csMemTPDLock);
auto it = m_MEM_TPD.find(iConfig);
if (it != m_MEM_TPD.end()) val = true;
LeaveCriticalSection(&csMemTPDLock);
}
return val;
}
void CMinecraftApp::GetTPD(int iConfig, std::uint8_t** ppbData,
unsigned int* pByteCount) {
EnterCriticalSection(&csMemTPDLock);
std::lock_guard<std::mutex> lock(csMemTPDLock);
auto it = m_MEM_TPD.find(iConfig);
if (it != m_MEM_TPD.end()) {
PMEMDATA pData = (*it).second;
*ppbData = pData->pbData;
*pByteCount = pData->byteCount;
}
LeaveCriticalSection(&csMemTPDLock);
}
// bool CMinecraftApp::UploadFileToGlobalStorage(int iQuadrant,
@ -5691,7 +5672,7 @@ DLC_INFO* CMinecraftApp::GetDLCInfoForFullOfferID(uint64_t ullOfferID_Full) {
}
void CMinecraftApp::EnterSaveNotificationSection() {
EnterCriticalSection(&m_saveNotificationCriticalSection);
std::lock_guard<std::mutex> lock(m_saveNotificationCriticalSection);
if (m_saveNotificationDepth++ == 0) {
if (g_NetworkManager
.IsInSession()) // this can be triggered from the front end if
@ -5707,11 +5688,10 @@ void CMinecraftApp::EnterSaveNotificationSection() {
}
}
}
LeaveCriticalSection(&m_saveNotificationCriticalSection);
}
void CMinecraftApp::LeaveSaveNotificationSection() {
EnterCriticalSection(&m_saveNotificationCriticalSection);
std::lock_guard<std::mutex> lock(m_saveNotificationCriticalSection);
if (--m_saveNotificationDepth == 0) {
if (g_NetworkManager
.IsInSession()) // this can be triggered from the front end if
@ -5727,7 +5707,6 @@ void CMinecraftApp::LeaveSaveNotificationSection() {
}
}
}
LeaveCriticalSection(&m_saveNotificationCriticalSection);
}
int CMinecraftApp::RemoteSaveThreadProc(void* lpParameter) {
@ -6662,7 +6641,7 @@ std::uint32_t CMinecraftApp::m_dwContentTypeA[e_Marketplace_MAX] = {
unsigned int CMinecraftApp::AddDLCRequest(eDLCMarketplaceType eType,
bool bPromote) {
// lock access
EnterCriticalSection(&csDLCDownloadQueue);
{ std::lock_guard<std::mutex> lock(csDLCDownloadQueue);
// If it's already in there, promote it to the top of the list
int iPosition = 0;
@ -6675,7 +6654,6 @@ unsigned int CMinecraftApp::AddDLCRequest(eDLCMarketplaceType eType,
if (pCurrent->eState == e_DLC_ContentState_Retrieving ||
pCurrent->eState == e_DLC_ContentState_Retrieved) {
// already retrieved this
LeaveCriticalSection(&csDLCDownloadQueue);
return 0;
} else {
// promote
@ -6685,7 +6663,6 @@ unsigned int CMinecraftApp::AddDLCRequest(eDLCMarketplaceType eType,
m_DLCDownloadQueue.insert(m_DLCDownloadQueue.begin(),
pCurrent);
}
LeaveCriticalSection(&csDLCDownloadQueue);
return 0;
}
}
@ -6699,7 +6676,7 @@ unsigned int CMinecraftApp::AddDLCRequest(eDLCMarketplaceType eType,
m_DLCDownloadQueue.push_back(pDLCreq);
m_bAllDLCContentRetrieved = false;
LeaveCriticalSection(&csDLCDownloadQueue);
}
app.DebugPrintf("[Consoles_App] Added DLC request.\n");
return 1;
@ -6708,7 +6685,7 @@ unsigned int CMinecraftApp::AddDLCRequest(eDLCMarketplaceType eType,
unsigned int CMinecraftApp::AddTMSPPFileTypeRequest(eDLCContentType eType,
bool bPromote) {
// lock access
EnterCriticalSection(&csTMSPPDownloadQueue);
std::lock_guard<std::mutex> lock(csTMSPPDownloadQueue);
// If it's already in there, promote it to the top of the list
int iPosition = 0;
@ -6742,7 +6719,6 @@ unsigned int CMinecraftApp::AddTMSPPFileTypeRequest(eDLCContentType eType,
if(bPromoted)
{
// re-ordered the list, so leave now
LeaveCriticalSection(&csTMSPPDownloadQueue);
return 0;
}
*/
@ -6889,22 +6865,19 @@ unsigned int CMinecraftApp::AddTMSPPFileTypeRequest(eDLCContentType eType,
}
}
LeaveCriticalSection(&csTMSPPDownloadQueue);
return 1;
}
bool CMinecraftApp::CheckTMSDLCCanStop() {
EnterCriticalSection(&csTMSPPDownloadQueue);
std::lock_guard<std::mutex> lock(csTMSPPDownloadQueue);
for (auto it = m_TMSPPDownloadQueue.begin();
it != m_TMSPPDownloadQueue.end(); ++it) {
TMSPPRequest* pCurrent = *it;
if (pCurrent->eState == e_TMS_ContentState_Retrieving) {
LeaveCriticalSection(&csTMSPPDownloadQueue);
return false;
}
}
LeaveCriticalSection(&csTMSPPDownloadQueue);
return true;
}
@ -6920,13 +6893,12 @@ bool CMinecraftApp::RetrieveNextDLCContent() {
// online.
}
EnterCriticalSection(&csDLCDownloadQueue);
{ std::lock_guard<std::mutex> lock(csDLCDownloadQueue);
for (auto it = m_DLCDownloadQueue.begin();
it != m_DLCDownloadQueue.end(); ++it) {
DLCRequest* pCurrent = *it;
if (pCurrent->eState == e_DLC_ContentState_Retrieving) {
LeaveCriticalSection(&csDLCDownloadQueue);
return true;
}
}
@ -6952,11 +6924,10 @@ bool CMinecraftApp::RetrieveNextDLCContent() {
app.DebugPrintf("RetrieveNextDLCContent - PROBLEM\n");
pCurrent->eState = e_DLC_ContentState_Retrieved;
}
LeaveCriticalSection(&csDLCDownloadQueue);
return true;
}
}
LeaveCriticalSection(&csDLCDownloadQueue);
}
app.DebugPrintf("[Consoles_App] Finished downloading dlc content.\n");
return false;
@ -6969,7 +6940,7 @@ int CMinecraftApp::TMSPPFileReturned(void* pParam, int iPad, int iUserData,
CMinecraftApp* pClass = (CMinecraftApp*)pParam;
// find the right one in the vector
EnterCriticalSection(&pClass->csTMSPPDownloadQueue);
{ std::lock_guard<std::mutex> lock(pClass->csTMSPPDownloadQueue);
for (auto it = pClass->m_TMSPPDownloadQueue.begin();
it != pClass->m_TMSPPDownloadQueue.end(); ++it) {
TMSPPRequest* pCurrent = *it;
@ -7008,7 +6979,7 @@ int CMinecraftApp::TMSPPFileReturned(void* pParam, int iPad, int iUserData,
break;
}
}
LeaveCriticalSection(&pClass->csTMSPPDownloadQueue);
}
return 0;
}
@ -7029,7 +7000,7 @@ void CMinecraftApp::ClearAndResetDLCDownloadQueue() {
app.DebugPrintf("[Consoles_App] Clear and reset download queue.\n");
int iPosition = 0;
EnterCriticalSection(&csTMSPPDownloadQueue);
{ std::lock_guard<std::mutex> lock(csTMSPPDownloadQueue);
for (auto it = m_DLCDownloadQueue.begin();
it != m_DLCDownloadQueue.end(); ++it) {
DLCRequest* pCurrent = *it;
@ -7039,7 +7010,7 @@ void CMinecraftApp::ClearAndResetDLCDownloadQueue() {
}
m_DLCDownloadQueue.clear();
m_bAllDLCContentRetrieved = true;
LeaveCriticalSection(&csTMSPPDownloadQueue);
}
}
void CMinecraftApp::TickTMSPPFilesRetrieved() {
@ -7051,7 +7022,7 @@ void CMinecraftApp::TickTMSPPFilesRetrieved() {
}
void CMinecraftApp::ClearTMSPPFilesRetrieved() {
int iPosition = 0;
EnterCriticalSection(&csTMSPPDownloadQueue);
{ std::lock_guard<std::mutex> lock(csTMSPPDownloadQueue);
for (auto it = m_TMSPPDownloadQueue.begin();
it != m_TMSPPDownloadQueue.end(); ++it) {
TMSPPRequest* pCurrent = *it;
@ -7061,7 +7032,7 @@ void CMinecraftApp::ClearTMSPPFilesRetrieved() {
}
m_TMSPPDownloadQueue.clear();
m_bAllTMSContentRetrieved = true;
LeaveCriticalSection(&csTMSPPDownloadQueue);
}
}
int CMinecraftApp::DLCOffersReturned(void* pParam, int iOfferC,
@ -7069,7 +7040,7 @@ int CMinecraftApp::DLCOffersReturned(void* pParam, int iOfferC,
CMinecraftApp* pClass = (CMinecraftApp*)pParam;
// find the right one in the vector
EnterCriticalSection(&pClass->csTMSPPDownloadQueue);
{ std::lock_guard<std::mutex> lock(pClass->csTMSPPDownloadQueue);
for (auto it = pClass->m_DLCDownloadQueue.begin();
it != pClass->m_DLCDownloadQueue.end(); ++it) {
DLCRequest* pCurrent = *it;
@ -7086,7 +7057,7 @@ int CMinecraftApp::DLCOffersReturned(void* pParam, int iOfferC,
break;
}
}
LeaveCriticalSection(&pClass->csTMSPPDownloadQueue);
}
return 0;
}
@ -7101,18 +7072,16 @@ eDLCContentType CMinecraftApp::Find_eDLCContentType(std::uint32_t dwType) {
bool CMinecraftApp::DLCContentRetrieved(eDLCMarketplaceType eType) {
// If there's already a retrieve in progress, quit
// we may have re-ordered the list, so need to check every item
EnterCriticalSection(&csDLCDownloadQueue);
std::lock_guard<std::mutex> lock(csDLCDownloadQueue);
for (auto it = m_DLCDownloadQueue.begin();
it != m_DLCDownloadQueue.end(); ++it) {
DLCRequest* pCurrent = *it;
if ((pCurrent->dwType == m_dwContentTypeA[eType]) &&
(pCurrent->eState == e_DLC_ContentState_Retrieved)) {
LeaveCriticalSection(&csDLCDownloadQueue);
return true;
}
}
LeaveCriticalSection(&csDLCDownloadQueue);
return false;
}
@ -7125,8 +7094,8 @@ void CMinecraftApp::SetAdditionalSkinBoxes(std::uint32_t dwSkinID,
std::vector<ModelPart*>* pvModelPart = new std::vector<ModelPart*>;
std::vector<SKIN_BOX*>* pvSkinBoxes = new std::vector<SKIN_BOX*>;
EnterCriticalSection(&csAdditionalModelParts);
EnterCriticalSection(&csAdditionalSkinBoxes);
{ std::lock_guard<std::mutex> lock_mp(csAdditionalModelParts);
std::lock_guard<std::mutex> lock_sb(csAdditionalSkinBoxes);
app.DebugPrintf(
"*** SetAdditionalSkinBoxes - Inserting model parts for skin %d from "
@ -7148,9 +7117,7 @@ void CMinecraftApp::SetAdditionalSkinBoxes(std::uint32_t dwSkinID,
m_AdditionalSkinBoxes.insert(
std::pair<std::uint32_t, std::vector<SKIN_BOX*>*>(dwSkinID,
pvSkinBoxes));
LeaveCriticalSection(&csAdditionalSkinBoxes);
LeaveCriticalSection(&csAdditionalModelParts);
}
}
std::vector<ModelPart*>* CMinecraftApp::SetAdditionalSkinBoxes(
@ -7160,8 +7127,8 @@ std::vector<ModelPart*>* CMinecraftApp::SetAdditionalSkinBoxes(
Model* pModel = renderer->getModel();
std::vector<ModelPart*>* pvModelPart = new std::vector<ModelPart*>;
EnterCriticalSection(&csAdditionalModelParts);
EnterCriticalSection(&csAdditionalSkinBoxes);
{ std::lock_guard<std::mutex> lock_mp(csAdditionalModelParts);
std::lock_guard<std::mutex> lock_sb(csAdditionalSkinBoxes);
app.DebugPrintf(
"*** SetAdditionalSkinBoxes - Inserting model parts for skin %d from "
"array of Skin Boxes\n",
@ -7181,15 +7148,13 @@ std::vector<ModelPart*>* CMinecraftApp::SetAdditionalSkinBoxes(
m_AdditionalSkinBoxes.insert(
std::pair<std::uint32_t, std::vector<SKIN_BOX*>*>(dwSkinID,
pvSkinBoxA));
LeaveCriticalSection(&csAdditionalSkinBoxes);
LeaveCriticalSection(&csAdditionalModelParts);
}
return pvModelPart;
}
std::vector<ModelPart*>* CMinecraftApp::GetAdditionalModelParts(
std::uint32_t dwSkinID) {
EnterCriticalSection(&csAdditionalModelParts);
std::lock_guard<std::mutex> lock(csAdditionalModelParts);
std::vector<ModelPart*>* pvModelParts = nullptr;
if (m_AdditionalModelParts.size() > 0) {
auto it = m_AdditionalModelParts.find(dwSkinID);
@ -7198,13 +7163,12 @@ std::vector<ModelPart*>* CMinecraftApp::GetAdditionalModelParts(
}
}
LeaveCriticalSection(&csAdditionalModelParts);
return pvModelParts;
}
std::vector<SKIN_BOX*>* CMinecraftApp::GetAdditionalSkinBoxes(
std::uint32_t dwSkinID) {
EnterCriticalSection(&csAdditionalSkinBoxes);
std::lock_guard<std::mutex> lock(csAdditionalSkinBoxes);
std::vector<SKIN_BOX*>* pvSkinBoxes = nullptr;
if (m_AdditionalSkinBoxes.size() > 0) {
auto it = m_AdditionalSkinBoxes.find(dwSkinID);
@ -7213,12 +7177,11 @@ std::vector<SKIN_BOX*>* CMinecraftApp::GetAdditionalSkinBoxes(
}
}
LeaveCriticalSection(&csAdditionalSkinBoxes);
return pvSkinBoxes;
}
unsigned int CMinecraftApp::GetAnimOverrideBitmask(std::uint32_t dwSkinID) {
EnterCriticalSection(&csAnimOverrideBitmask);
std::lock_guard<std::mutex> lock(csAnimOverrideBitmask);
unsigned int uiAnimOverrideBitmask = 0L;
if (m_AnimOverrides.size() > 0) {
@ -7228,25 +7191,22 @@ unsigned int CMinecraftApp::GetAnimOverrideBitmask(std::uint32_t dwSkinID) {
}
}
LeaveCriticalSection(&csAnimOverrideBitmask);
return uiAnimOverrideBitmask;
}
void CMinecraftApp::SetAnimOverrideBitmask(std::uint32_t dwSkinID,
unsigned int uiAnimOverrideBitmask) {
// Make thread safe
EnterCriticalSection(&csAnimOverrideBitmask);
std::lock_guard<std::mutex> lock(csAnimOverrideBitmask);
if (m_AnimOverrides.size() > 0) {
auto it = m_AnimOverrides.find(dwSkinID);
if (it != m_AnimOverrides.end()) {
LeaveCriticalSection(&csAnimOverrideBitmask);
return; // already in here
}
}
m_AnimOverrides.insert(std::pair<std::uint32_t, unsigned int>(
dwSkinID, uiAnimOverrideBitmask));
LeaveCriticalSection(&csAnimOverrideBitmask);
}
std::uint32_t CMinecraftApp::getSkinIdFromPath(const std::wstring& skin) {

View file

@ -1,6 +1,7 @@
#pragma once
#include <cstdint>
#include <mutex>
// using namespace std;
@ -462,8 +463,8 @@ private:
std::unordered_map<std::wstring, PMEMDATA> m_MEM_Files;
// for storing texture pack data files
std::unordered_map<int, PMEMDATA> m_MEM_TPD;
CRITICAL_SECTION csMemFilesLock; // For locking access to the above map
CRITICAL_SECTION csMemTPDLock; // For locking access to the above map
std::mutex csMemFilesLock; // For locking access to the above map
std::mutex csMemTPDLock; // For locking access to the above map
VNOTIFICATIONS m_vNotifications;
@ -885,7 +886,7 @@ public:
void LeaveSaveNotificationSection();
private:
CRITICAL_SECTION m_saveNotificationCriticalSection;
std::mutex m_saveNotificationCriticalSection;
int m_saveNotificationDepth;
// Download Status
@ -897,11 +898,11 @@ private:
bool m_bAllDLCContentRetrieved;
bool m_bAllTMSContentRetrieved;
bool m_bTickTMSDLCFiles;
CRITICAL_SECTION csDLCDownloadQueue;
CRITICAL_SECTION csTMSPPDownloadQueue;
CRITICAL_SECTION csAdditionalModelParts;
CRITICAL_SECTION csAdditionalSkinBoxes;
CRITICAL_SECTION csAnimOverrideBitmask;
std::mutex csDLCDownloadQueue;
std::mutex csTMSPPDownloadQueue;
std::mutex csAdditionalModelParts;
std::mutex csAdditionalSkinBoxes;
std::mutex csAnimOverrideBitmask;
bool m_bCorruptSaveDeleted;
std::uint32_t m_dwAdditionalModelParts[XUSER_MAX_COUNT];

View file

@ -33,7 +33,6 @@ SonyLeaderboardManager::SonyLeaderboardManager() {
m_openSessions = 0;
InitializeCriticalSection(&m_csViewsLock);
m_running = false;
m_threadScoreboard = nullptr;
@ -51,7 +50,6 @@ SonyLeaderboardManager::~SonyLeaderboardManager() {
delete m_threadScoreboard;
DeleteCriticalSection(&m_csViewsLock);
}
int SonyLeaderboardManager::scoreboardThreadEntry(void* lpParam) {
@ -68,9 +66,9 @@ int SonyLeaderboardManager::scoreboardThreadEntry(void* lpParam) {
self->scoreboardThreadInternal();
}
EnterCriticalSection(&self->m_csViewsLock);
{ std::lock_guard<std::mutex> lock(self->m_csViewsLock);
needsWriting = self->m_views.size() > 0;
LeaveCriticalSection(&self->m_csViewsLock);
}
// 4J Stu - We can't write while we aren't signed in to live
if (!ProfileManager.IsSignedInLive(ProfileManager.GetPrimaryPad())) {
@ -166,9 +164,10 @@ void SonyLeaderboardManager::scoreboardThreadInternal() {
// 4J-JEV: Writing no longer changes the manager state,
// we'll manage the write queue seperately.
EnterCriticalSection(&m_csViewsLock);
bool hasWork = !m_views.empty();
LeaveCriticalSection(&m_csViewsLock);
bool hasWork;
{ std::lock_guard<std::mutex> lock(m_csViewsLock);
hasWork = !m_views.empty();
}
if (hasWork) {
setScore();
@ -495,10 +494,11 @@ bool SonyLeaderboardManager::setScore() {
// Get next job.
EnterCriticalSection(&m_csViewsLock);
RegisterScore rscore = m_views.front();
RegisterScore rscore;
{ std::lock_guard<std::mutex> lock(m_csViewsLock);
rscore = m_views.front();
m_views.pop();
LeaveCriticalSection(&m_csViewsLock);
}
if (ProfileManager.IsGuest(rscore.m_iPad)) {
app.DebugPrintf(
@ -521,9 +521,8 @@ bool SonyLeaderboardManager::setScore() {
// Start emptying queue if leaderboards has been closed.
if (ret == SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED) {
EnterCriticalSection(&m_csViewsLock);
std::lock_guard<std::mutex> lock(m_csViewsLock);
m_views.pop();
LeaveCriticalSection(&m_csViewsLock);
}
// Error handling.
@ -685,7 +684,7 @@ bool SonyLeaderboardManager::WriteStats(unsigned int viewCount, ViewIn views) {
// Write relevant parameters.
// RegisterScore *regScore = reinterpret_cast<RegisterScore *>(views);
EnterCriticalSection(&m_csViewsLock);
{ std::lock_guard<std::mutex> lock(m_csViewsLock);
for (int i = 0; i < viewCount; i++) {
app.DebugPrintf(
"[SonyLeaderboardManager] WriteStats(), starting. difficulty=%i, "
@ -695,7 +694,7 @@ bool SonyLeaderboardManager::WriteStats(unsigned int viewCount, ViewIn views) {
m_views.push(views[i]);
}
LeaveCriticalSection(&m_csViewsLock);
}
delete[] views; //*regScore;

View file

@ -1,4 +1,5 @@
#pragma once
#include <mutex>
#include "Common/Leaderboards/LeaderboardManager.h"
@ -40,7 +41,7 @@ protected:
std::queue<RegisterScore> m_views;
CRITICAL_SECTION m_csViewsLock;
std::mutex m_csViewsLock;
EStatsState m_eStatsState; // State of the stats read
// EFilterMode m_eFilterMode;

View file

@ -5,6 +5,7 @@
#include "../../Minecraft.Client/Level/MultiPlayerLevel.h"
#include "../../Minecraft.World/Headers/net.minecraft.world.level.dimension.h"
#include "../../Minecraft.World/Headers/net.minecraft.world.level.storage.h"
#include <mutex>
UIComponent_Panorama::UIComponent_Panorama(int iPad, void* initData,
UILayer* parentLayer)
@ -42,25 +43,26 @@ void UIComponent_Panorama::tick() {
if (!hasMovie()) return;
Minecraft* pMinecraft = Minecraft::GetInstance();
EnterCriticalSection(&pMinecraft->m_setLevelCS);
if (pMinecraft->level != nullptr) {
int64_t i64TimeOfDay = 0;
// are we in the Nether? - Leave the time as 0 if we are, so we show
// daylight
if (pMinecraft->level->dimension->id == 0) {
i64TimeOfDay =
pMinecraft->level->getLevelData()->getGameTime() % 24000;
}
{
std::lock_guard<std::mutex> lock(pMinecraft->m_setLevelCS);
if (pMinecraft->level != nullptr) {
int64_t i64TimeOfDay = 0;
// are we in the Nether? - Leave the time as 0 if we are, so we show
// daylight
if (pMinecraft->level->dimension->id == 0) {
i64TimeOfDay =
pMinecraft->level->getLevelData()->getGameTime() % 24000;
}
if (i64TimeOfDay > 14000) {
setPanorama(false);
if (i64TimeOfDay > 14000) {
setPanorama(false);
} else {
setPanorama(true);
}
} else {
setPanorama(true);
}
} else {
setPanorama(true);
}
LeaveCriticalSection(&pMinecraft->m_setLevelCS);
UIScene::tick();
}

View file

@ -34,7 +34,7 @@
#endif
CRITICAL_SECTION UIController::ms_reloadSkinCS;
std::mutex UIController::ms_reloadSkinCS;
bool UIController::ms_bReloadSkinCSInitialised = false;
std::uint32_t UIController::m_dwTrialTimerLimitSecs =
@ -125,7 +125,7 @@ static void* RADLINK AllocateFunction(void* alloc_callback_user_data,
size_t size_requested,
size_t* size_returned) {
UIController* controller = (UIController*)alloc_callback_user_data;
EnterCriticalSection(&controller->m_Allocatorlock);
std::lock_guard<std::mutex> lock(controller->m_Allocatorlock);
#if defined(EXCLUDE_IGGY_ALLOCATIONS_FROM_HEAP_INSPECTOR)
void* alloc = __real_malloc(size_requested);
#else
@ -136,14 +136,13 @@ static void* RADLINK AllocateFunction(void* alloc_callback_user_data,
allocations[alloc] = size_requested;
app.DebugPrintf(app.USER_SR, "Allocating %d, new total: %d\n",
size_requested, UIController::iggyAllocCount);
LeaveCriticalSection(&controller->m_Allocatorlock);
return alloc;
}
static void RADLINK DeallocateFunction(void* alloc_callback_user_data,
void* ptr) {
UIController* controller = (UIController*)alloc_callback_user_data;
EnterCriticalSection(&controller->m_Allocatorlock);
std::lock_guard<std::mutex> lock(controller->m_Allocatorlock);
size_t size = allocations[ptr];
UIController::iggyAllocCount -= size;
allocations.erase(ptr);
@ -154,7 +153,6 @@ static void RADLINK DeallocateFunction(void* alloc_callback_user_data,
#else
free(ptr);
#endif
LeaveCriticalSection(&controller->m_Allocatorlock);
}
UIController::UIController() {
@ -173,7 +171,7 @@ UIController::UIController() {
m_eCurrentFont = m_eTargetFont = eFont_NotLoaded;
#if defined(ENABLE_IGGY_ALLOCATOR)
InitializeCriticalSection(&m_Allocatorlock);
// std::mutex is default-constructed, no initialization needed
#endif
// 4J Stu - This is a bit of a hack until we change the Minecraft
@ -214,15 +212,12 @@ UIController::UIController() {
m_accumulatedTicks = 0;
m_lastUiSfx = 0;
InitializeCriticalSection(&m_navigationLock);
InitializeCriticalSection(&m_registeredCallbackScenesCS);
// m_bSysUIShowing=false;
m_bSystemUIShowing = false;
if (!ms_bReloadSkinCSInitialised) {
// MGH - added to prevent crash loading Iggy movies while the skins were
// being reloaded
InitializeCriticalSection(&ms_reloadSkinCS);
ms_bReloadSkinCSInitialised = true;
}
}
@ -620,27 +615,27 @@ void UIController::StartReloadSkinThread() {
}
int UIController::reloadSkinThreadProc(void* lpParam) {
EnterCriticalSection(
&ms_reloadSkinCS); // MGH - added to prevent crash loading Iggy movies
// while the skins were being reloaded
UIController* controller = (UIController*)lpParam;
// Load new skin
controller->loadSkins();
{
std::lock_guard<std::mutex> lock(ms_reloadSkinCS); // MGH - added to prevent crash loading Iggy movies
// while the skins were being reloaded
UIController* controller = (UIController*)lpParam;
// Load new skin
controller->loadSkins();
// Reload all scene swf
for (int i = eUIGroup_Player1; i < eUIGroup_COUNT; ++i) {
controller->m_groups[i]->ReloadAll();
}
// Reload all scene swf
for (int i = eUIGroup_Player1; i < eUIGroup_COUNT; ++i) {
controller->m_groups[i]->ReloadAll();
}
// Always reload the fullscreen group
controller->m_groups[eUIGroup_Fullscreen]->ReloadAll();
// Always reload the fullscreen group
controller->m_groups[eUIGroup_Fullscreen]->ReloadAll();
// 4J Stu - Don't do this on windows, as we never navigated forwards to
// start with
// 4J Stu - Don't do this on windows, as we never navigated forwards to
// start with
#if !(defined(_WINDOWS64) || defined(__linux__))
controller->NavigateBack(0, false, eUIScene_COUNT, eUILayer_Tooltips);
controller->NavigateBack(0, false, eUIScene_COUNT, eUILayer_Tooltips);
#endif
LeaveCriticalSection(&ms_reloadSkinCS);
}
return 0;
}
@ -1256,13 +1251,15 @@ bool UIController::NavigateToScene(int iPad, EUIScene scene, void* initData,
PerformanceTimer timer;
EnterCriticalSection(&m_navigationLock);
SetMenuDisplayed(menuDisplayedPad, true);
bool success =
m_groups[(int)group]->NavigateToScene(iPad, scene, initData, layer);
if (success && group == eUIGroup_Fullscreen)
setFullscreenMenuDisplayed(true);
LeaveCriticalSection(&m_navigationLock);
bool success;
{
std::lock_guard<std::mutex> lock(m_navigationLock);
SetMenuDisplayed(menuDisplayedPad, true);
success =
m_groups[(int)group]->NavigateToScene(iPad, scene, initData, layer);
if (success && group == eUIGroup_Fullscreen)
setFullscreenMenuDisplayed(true);
}
timer.PrintElapsedTime(L"Navigate to scene");
@ -1380,24 +1377,22 @@ UIScene* UIController::GetTopScene(int iPad, EUILayer layer, EUIGroup group) {
}
size_t UIController::RegisterForCallbackId(UIScene* scene) {
EnterCriticalSection(&m_registeredCallbackScenesCS);
std::lock_guard<std::mutex> lock(m_registeredCallbackScenesCS);
size_t newId = GetTickCount();
newId &= 0xFFFFFF; // Chop off the top byte, we don't need any more
// accuracy than that
newId |= (scene->getSceneType()
<< 24); // Add in the scene's type to help keep this unique
m_registeredCallbackScenes[newId] = scene;
LeaveCriticalSection(&m_registeredCallbackScenesCS);
return newId;
}
void UIController::UnregisterCallbackId(size_t id) {
EnterCriticalSection(&m_registeredCallbackScenesCS);
std::lock_guard<std::mutex> lock(m_registeredCallbackScenesCS);
auto it = m_registeredCallbackScenes.find(id);
if (it != m_registeredCallbackScenes.end()) {
m_registeredCallbackScenes.erase(it);
}
LeaveCriticalSection(&m_registeredCallbackScenesCS);
}
UIScene* UIController::GetSceneFromCallbackId(size_t id) {
@ -1410,11 +1405,11 @@ UIScene* UIController::GetSceneFromCallbackId(size_t id) {
}
void UIController::EnterCallbackIdCriticalSection() {
EnterCriticalSection(&m_registeredCallbackScenesCS);
m_registeredCallbackScenesCS.lock();
}
void UIController::LeaveCallbackIdCriticalSection() {
LeaveCriticalSection(&m_registeredCallbackScenesCS);
m_registeredCallbackScenesCS.unlock();
}
void UIController::CloseAllPlayersScenes() {

View file

@ -1,6 +1,7 @@
#pragma once
// using namespace std;
#include <cstdint>
#include <mutex>
#include "IUIController.h"
#include "UIEnums.h"
@ -20,7 +21,7 @@ public:
// MGH - added to prevent crash loading Iggy movies while the skins were
// being reloaded
static CRITICAL_SECTION ms_reloadSkinCS;
static std::mutex ms_reloadSkinCS;
static bool ms_bReloadSkinCSInitialised;
protected:
@ -28,7 +29,7 @@ protected:
UIComponent_DebugUIMarketingGuide* m_uiDebugMarketingGuide;
private:
CRITICAL_SECTION m_navigationLock;
std::mutex m_navigationLock;
static const int UI_REPEAT_KEY_DELAY_MS =
300; // How long from press until the first repeat
@ -165,7 +166,7 @@ private:
// that are used in async callbacks so we
// can safely handle when they get
// destroyed
CRITICAL_SECTION m_registeredCallbackScenesCS;
std::mutex m_registeredCallbackScenesCS;
;
public:
@ -190,7 +191,7 @@ protected:
void postInit();
public:
CRITICAL_SECTION m_Allocatorlock;
std::mutex m_Allocatorlock;
void SetupFont();
bool PendingFontChange();
bool UsingBitmapFont();

View file

@ -1,4 +1,5 @@
#include "../../Minecraft.World/Platform/stdafx.h"
#include <mutex>
#include "UI.h"
#include "UIScene.h"
@ -245,12 +246,11 @@ bool UIScene::mapElementsAndNames() {
return true;
}
extern CRITICAL_SECTION s_loadSkinCS;
extern std::mutex s_loadSkinCS;
void UIScene::loadMovie() {
EnterCriticalSection(
&UIController::ms_reloadSkinCS); // MGH - added to prevent crash
// loading Iggy movies while the skins
// were being reloaded
UIController::ms_reloadSkinCS.lock(); // MGH - added to prevent crash
// loading Iggy movies while the skins
// were being reloaded
std::wstring moviePath = getMoviePath();
#if defined(_WINDOWS64)
@ -320,7 +320,7 @@ void UIScene::loadMovie() {
IggyPlayerSetUserdata(swf, this);
// #ifdef _DEBUG
LeaveCriticalSection(&UIController::ms_reloadSkinCS);
UIController::ms_reloadSkinCS.unlock();
}
void UIScene::getDebugMemoryUseRecursive(const std::wstring& moviePath,

View file

@ -4,6 +4,7 @@
#include "../../../Minecraft.World/Platform/stdafx.h"
#include <assert.h>
#include <mutex>
// #include <system_service.h>
#if defined(__linux__) && defined(__GLIBC__)
#include <signal.h>
@ -1046,7 +1047,7 @@ bool trackStarted = false;
volatile size_t sizeCheckMin = 1160;
volatile size_t sizeCheckMax = 1160;
volatile int sectCheck = 48;
CRITICAL_SECTION memCS;
std::mutex memCS;
uint32_t tlsIdx;
void* XMemAlloc(size_t dwSize, uint32_t dwAllocAttributes) {
@ -1057,33 +1058,34 @@ void* XMemAlloc(size_t dwSize, uint32_t dwAllocAttributes) {
return p;
}
EnterCriticalSection(&memCS);
void* p;
{
std::lock_guard<std::mutex> lock(memCS);
void* p = XMemAllocDefault(dwSize + 16, dwAllocAttributes);
size_t realSize = XMemSizeDefault(p, dwAllocAttributes) - 16;
p = XMemAllocDefault(dwSize + 16, dwAllocAttributes);
size_t realSize = XMemSizeDefault(p, dwAllocAttributes) - 16;
if (trackEnable) {
int sect = ((int)TlsGetValue(tlsIdx)) & 0x3f;
*(((unsigned char*)p) + realSize) = sect;
if (trackEnable) {
int sect = ((int)TlsGetValue(tlsIdx)) & 0x3f;
*(((unsigned char*)p) + realSize) = sect;
if ((realSize >= sizeCheckMin) && (realSize <= sizeCheckMax) &&
((sect == sectCheck) || (sectCheck == -1))) {
app.DebugPrintf("Found one\n");
}
if ((realSize >= sizeCheckMin) && (realSize <= sizeCheckMax) &&
((sect == sectCheck) || (sectCheck == -1))) {
app.DebugPrintf("Found one\n");
}
if (p) {
totalAllocGen += realSize;
trackEnable = false;
int key = (sect << 26) | realSize;
int oldCount = allocCounts[key];
allocCounts[key] = oldCount + 1;
if (p) {
totalAllocGen += realSize;
trackEnable = false;
int key = (sect << 26) | realSize;
int oldCount = allocCounts[key];
allocCounts[key] = oldCount + 1;
trackEnable = true;
trackEnable = true;
}
}
}
LeaveCriticalSection(&memCS);
return p;
}
@ -1114,22 +1116,23 @@ void WINAPI XMemFree(void* pAddress, uint32_t dwAllocAttributes) {
totalAllocGen -= realSize;
return;
}
EnterCriticalSection(&memCS);
if (pAddress) {
size_t realSize = XMemSizeDefault(pAddress, dwAllocAttributes) - 16;
{
std::lock_guard<std::mutex> lock(memCS);
if (pAddress) {
size_t realSize = XMemSizeDefault(pAddress, dwAllocAttributes) - 16;
if (trackEnable) {
int sect = *(((unsigned char*)pAddress) + realSize);
totalAllocGen -= realSize;
trackEnable = false;
int key = (sect << 26) | realSize;
int oldCount = allocCounts[key];
allocCounts[key] = oldCount - 1;
trackEnable = true;
if (trackEnable) {
int sect = *(((unsigned char*)pAddress) + realSize);
totalAllocGen -= realSize;
trackEnable = false;
int key = (sect << 26) | realSize;
int oldCount = allocCounts[key];
allocCounts[key] = oldCount - 1;
trackEnable = true;
}
XMemFreeDefault(pAddress, dwAllocAttributes);
}
XMemFreeDefault(pAddress, dwAllocAttributes);
}
LeaveCriticalSection(&memCS);
}
size_t WINAPI XMemSize(void* pAddress, uint32_t dwAllocAttributes) {
@ -1158,14 +1161,14 @@ void ResetMem() {
trackEnable = true;
trackStarted = true;
totalAllocGen = 0;
InitializeCriticalSection(&memCS);
tlsIdx = TlsAlloc();
}
EnterCriticalSection(&memCS);
trackEnable = false;
allocCounts.clear();
trackEnable = true;
LeaveCriticalSection(&memCS);
{
std::lock_guard<std::mutex> lock(memCS);
trackEnable = false;
allocCounts.clear();
trackEnable = true;
}
}
void MemSect(int section) {

View file

@ -249,46 +249,6 @@ typedef HINSTANCE HMODULE;
#define E_ABORT _HRESULT_TYPEDEF_(0x80004004L)
#define E_NOINTERFACE _HRESULT_TYPEDEF_(0x80004002L)
typedef pthread_mutex_t RTL_CRITICAL_SECTION;
typedef pthread_mutex_t* PRTL_CRITICAL_SECTION;
typedef RTL_CRITICAL_SECTION CRITICAL_SECTION;
typedef PRTL_CRITICAL_SECTION PCRITICAL_SECTION;
typedef PRTL_CRITICAL_SECTION LPCRITICAL_SECTION;
static inline void InitializeCriticalSection(
PRTL_CRITICAL_SECTION CriticalSection) {
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(CriticalSection, &attr);
pthread_mutexattr_destroy(&attr);
}
static inline void InitializeCriticalSectionAndSpinCount(
PRTL_CRITICAL_SECTION CriticalSection, ULONG SpinCount) {
// no spin count required because we use a recursive mutex
InitializeCriticalSection(CriticalSection);
}
static inline void DeleteCriticalSection(
PRTL_CRITICAL_SECTION CriticalSection) {
pthread_mutex_destroy(CriticalSection);
}
static inline void EnterCriticalSection(PRTL_CRITICAL_SECTION CriticalSection) {
pthread_mutex_lock(CriticalSection);
}
static inline void LeaveCriticalSection(PRTL_CRITICAL_SECTION CriticalSection) {
pthread_mutex_unlock(CriticalSection);
}
static inline ULONG TryEnterCriticalSection(
PRTL_CRITICAL_SECTION CriticalSection) {
return pthread_mutex_trylock(CriticalSection) == 0;
}
// https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-globalmemorystatus
static inline void GlobalMemoryStatus(LPMEMORYSTATUS lpBuffer) {
// TODO: Parse /proc/meminfo and set lpBuffer based on that. Probably will

View file

@ -4,6 +4,7 @@
#include "../../../Minecraft.World/Platform/stdafx.h"
#include <assert.h>
#include <mutex>
#include "GameConfig/Minecraft.spa.h"
#include "../../MinecraftServer.h"
#include "../../Player/LocalPlayer.h"
@ -932,7 +933,7 @@ bool trackStarted = false;
volatile size_t sizeCheckMin = 1160;
volatile size_t sizeCheckMax = 1160;
volatile int sectCheck = 48;
CRITICAL_SECTION memCS;
std::mutex memCS;
uint32_t tlsIdx;
void* XMemAlloc(size_t dwSize, uint32_t dwAllocAttributes) {
@ -943,33 +944,34 @@ void* XMemAlloc(size_t dwSize, uint32_t dwAllocAttributes) {
return p;
}
EnterCriticalSection(&memCS);
void* p;
{
std::lock_guard<std::mutex> lock(memCS);
void* p = XMemAllocDefault(dwSize + 16, dwAllocAttributes);
size_t realSize = XMemSizeDefault(p, dwAllocAttributes) - 16;
p = XMemAllocDefault(dwSize + 16, dwAllocAttributes);
size_t realSize = XMemSizeDefault(p, dwAllocAttributes) - 16;
if (trackEnable) {
int sect = ((int)TlsGetValue(tlsIdx)) & 0x3f;
*(((unsigned char*)p) + realSize) = sect;
if (trackEnable) {
int sect = ((int)TlsGetValue(tlsIdx)) & 0x3f;
*(((unsigned char*)p) + realSize) = sect;
if ((realSize >= sizeCheckMin) && (realSize <= sizeCheckMax) &&
((sect == sectCheck) || (sectCheck == -1))) {
app.DebugPrintf("Found one\n");
}
if ((realSize >= sizeCheckMin) && (realSize <= sizeCheckMax) &&
((sect == sectCheck) || (sectCheck == -1))) {
app.DebugPrintf("Found one\n");
}
if (p) {
totalAllocGen += realSize;
trackEnable = false;
int key = (sect << 26) | realSize;
int oldCount = allocCounts[key];
allocCounts[key] = oldCount + 1;
if (p) {
totalAllocGen += realSize;
trackEnable = false;
int key = (sect << 26) | realSize;
int oldCount = allocCounts[key];
allocCounts[key] = oldCount + 1;
trackEnable = true;
trackEnable = true;
}
}
}
LeaveCriticalSection(&memCS);
return p;
}
@ -1000,22 +1002,23 @@ void WINAPI XMemFree(void* pAddress, uint32_t dwAllocAttributes) {
totalAllocGen -= realSize;
return;
}
EnterCriticalSection(&memCS);
if (pAddress) {
size_t realSize = XMemSizeDefault(pAddress, dwAllocAttributes) - 16;
{
std::lock_guard<std::mutex> lock(memCS);
if (pAddress) {
size_t realSize = XMemSizeDefault(pAddress, dwAllocAttributes) - 16;
if (trackEnable) {
int sect = *(((unsigned char*)pAddress) + realSize);
totalAllocGen -= realSize;
trackEnable = false;
int key = (sect << 26) | realSize;
int oldCount = allocCounts[key];
allocCounts[key] = oldCount - 1;
trackEnable = true;
if (trackEnable) {
int sect = *(((unsigned char*)pAddress) + realSize);
totalAllocGen -= realSize;
trackEnable = false;
int key = (sect << 26) | realSize;
int oldCount = allocCounts[key];
allocCounts[key] = oldCount - 1;
trackEnable = true;
}
XMemFreeDefault(pAddress, dwAllocAttributes);
}
XMemFreeDefault(pAddress, dwAllocAttributes);
}
LeaveCriticalSection(&memCS);
}
size_t WINAPI XMemSize(void* pAddress, uint32_t dwAllocAttributes) {
@ -1044,14 +1047,14 @@ void ResetMem() {
trackEnable = true;
trackStarted = true;
totalAllocGen = 0;
InitializeCriticalSection(&memCS);
tlsIdx = TlsAlloc();
}
EnterCriticalSection(&memCS);
trackEnable = false;
allocCounts.clear();
trackEnable = true;
LeaveCriticalSection(&memCS);
{
std::lock_guard<std::mutex> lock(memCS);
trackEnable = false;
allocCounts.clear();
trackEnable = true;
}
}
void MemSect(int section) {

View file

@ -9,6 +9,7 @@
#include "LevelRenderer.h"
#include "../Utils/FrameProfiler.h"
#include <unordered_set>
#include <mutex>
int Chunk::updates = 0;
@ -92,7 +93,7 @@ void Chunk::reconcileRenderableTileEntities(
// TODO - 4J see how input entity vector is set up and decide what way is best
// to pass this to the function
Chunk::Chunk(Level* level, LevelRenderer::rteMap& globalRenderableTileEntities,
CRITICAL_SECTION& globalRenderableTileEntities_cs, int x, int y,
std::mutex& globalRenderableTileEntities_cs, int x, int y,
int z, ClipChunk* clipChunk)
: globalRenderableTileEntities(&globalRenderableTileEntities),
globalRenderableTileEntities_cs(&globalRenderableTileEntities_cs) {
@ -149,31 +150,31 @@ void Chunk::setPos(int x, int y, int z) {
assigned = true;
EnterCriticalSection(&levelRenderer->m_csDirtyChunks);
unsigned char refCount =
levelRenderer->incGlobalChunkRefCount(x, y, z, level);
// printf("\t\t [inc] refcount %d at %d, %d, %d\n",refCount,x,y,z);
{
std::lock_guard<std::mutex> lock(levelRenderer->m_csDirtyChunks);
unsigned char refCount =
levelRenderer->incGlobalChunkRefCount(x, y, z, level);
// printf("\t\t [inc] refcount %d at %d, %d, %d\n",refCount,x,y,z);
// int idx = levelRenderer->getGlobalIndexForChunk(x, y, z, level);
// int idx = levelRenderer->getGlobalIndexForChunk(x, y, z, level);
// If we're the first thing to be referencing this, mark it up as dirty to
// get rebuilt
if (refCount == 1) {
// printf("Setting %d %d %d dirty [%d]\n",x,y,z, idx);
// Chunks being made dirty in this way can be very numerous (eg the full
// visible area of the world at start up, or a whole edge of the world
// when moving). On account of this, don't want to stick them into our
// lock free queue that we would normally use for letting the render
// update thread know about this chunk. Instead, just set the flag to
// say this is dirty, and then pass a special value of 1 through to the
// lock free stack which lets that thread know that at least one chunk
// other than the ones in the stack itself have been made dirty.
levelRenderer->setGlobalChunkFlag(x, y, z, level,
LevelRenderer::CHUNK_FLAG_DIRTY);
PIXSetMarkerDeprecated(0, "Non-stack event pushed");
// If we're the first thing to be referencing this, mark it up as dirty to
// get rebuilt
if (refCount == 1) {
// printf("Setting %d %d %d dirty [%d]\n",x,y,z, idx);
// Chunks being made dirty in this way can be very numerous (eg the full
// visible area of the world at start up, or a whole edge of the world
// when moving). On account of this, don't want to stick them into our
// lock free queue that we would normally use for letting the render
// update thread know about this chunk. Instead, just set the flag to
// say this is dirty, and then pass a special value of 1 through to the
// lock free stack which lets that thread know that at least one chunk
// other than the ones in the stack itself have been made dirty.
levelRenderer->setGlobalChunkFlag(x, y, z, level,
LevelRenderer::CHUNK_FLAG_DIRTY);
PIXSetMarkerDeprecated(0, "Non-stack event pushed");
}
}
LeaveCriticalSection(&levelRenderer->m_csDirtyChunks);
}
void Chunk::translateToPos() {
@ -533,9 +534,10 @@ void Chunk::rebuild() {
// globally in the levelrenderer, in a hashmap with a special key made up
// from the dimension and chunk position (using same index as is used for
// global flags)
EnterCriticalSection(globalRenderableTileEntities_cs);
reconcileRenderableTileEntities(renderableTileEntities);
LeaveCriticalSection(globalRenderableTileEntities_cs);
{
std::lock_guard<std::mutex> lock(*globalRenderableTileEntities_cs);
reconcileRenderableTileEntities(renderableTileEntities);
}
PIXEndNamedEvent();
// 4J - These removed items are now also removed from
@ -710,27 +712,28 @@ void Chunk::reset() {
int oldKey = -1;
bool retireRenderableTileEntities = false;
EnterCriticalSection(&levelRenderer->m_csDirtyChunks);
oldKey = levelRenderer->getGlobalIndexForChunk(x, y, z, level);
unsigned char refCount =
levelRenderer->decGlobalChunkRefCount(x, y, z, level);
assigned = false;
// printf("\t\t [dec] refcount %d at %d, %d,
//%d\n",refCount,x,y,z);
if (refCount == 0 && oldKey != -1) {
retireRenderableTileEntities = true;
int lists = oldKey * 2;
if (lists >= 0) {
lists += levelRenderer->chunkLists;
for (int i = 0; i < 2; i++) {
// 4J - added - clear any renderer data associated with this
// unused list
RenderManager.CBuffClear(lists + i);
{
std::lock_guard<std::mutex> lock(levelRenderer->m_csDirtyChunks);
oldKey = levelRenderer->getGlobalIndexForChunk(x, y, z, level);
unsigned char refCount =
levelRenderer->decGlobalChunkRefCount(x, y, z, level);
assigned = false;
// printf("\t\t [dec] refcount %d at %d, %d,
//%d\n",refCount,x,y,z);
if (refCount == 0 && oldKey != -1) {
retireRenderableTileEntities = true;
int lists = oldKey * 2;
if (lists >= 0) {
lists += levelRenderer->chunkLists;
for (int i = 0; i < 2; i++) {
// 4J - added - clear any renderer data associated with this
// unused list
RenderManager.CBuffClear(lists + i);
}
levelRenderer->setGlobalChunkFlags(x, y, z, level, 0);
}
levelRenderer->setGlobalChunkFlags(x, y, z, level, 0);
}
}
LeaveCriticalSection(&levelRenderer->m_csDirtyChunks);
if (retireRenderableTileEntities) {
levelRenderer->retireRenderableTileEntitiesForChunkKey(oldKey);

View file

@ -56,12 +56,12 @@ public:
private:
LevelRenderer::rteMap* globalRenderableTileEntities;
CRITICAL_SECTION* globalRenderableTileEntities_cs;
std::mutex* globalRenderableTileEntities_cs;
bool assigned;
public:
Chunk(Level* level, LevelRenderer::rteMap& globalRenderableTileEntities,
CRITICAL_SECTION& globalRenderableTileEntities_cs, int x, int y,
std::mutex& globalRenderableTileEntities_cs, int x, int y,
int z, ClipChunk* clipChunk);
Chunk();

View file

@ -4,7 +4,7 @@
#include "ProgressRenderer.h"
#include "../../../Minecraft.World/Platform/System.h"
CRITICAL_SECTION ProgressRenderer::s_progress;
std::mutex ProgressRenderer::s_progress;
ProgressRenderer::ProgressRenderer(Minecraft* minecraft) {
status = -1;
@ -33,10 +33,11 @@ void ProgressRenderer::_progressStart(int title) {
// throw new StopGameException(); // 4J - removed
}
EnterCriticalSection(&ProgressRenderer::s_progress);
lastPercent = 0;
this->title = title;
LeaveCriticalSection(&ProgressRenderer::s_progress);
{
std::lock_guard<std::mutex> lock(ProgressRenderer::s_progress);
lastPercent = 0;
this->title = title;
}
}
@ -47,10 +48,11 @@ void ProgressRenderer::progressStage(int status) {
}
lastTime = 0;
EnterCriticalSection(&ProgressRenderer::s_progress);
setType(eProgressStringType_ID);
this->status = status;
LeaveCriticalSection(&ProgressRenderer::s_progress);
{
std::lock_guard<std::mutex> lock(ProgressRenderer::s_progress);
m_eType = eProgressStringType_ID;
this->status = status;
}
progressStagePercentage(-1);
lastTime = 0;
}
@ -58,57 +60,62 @@ void ProgressRenderer::progressStage(int status) {
void ProgressRenderer::progressStagePercentage(int i) {
// 4J Stu - Removing all progressRenderer rendering. This will be replaced
// on the xbox
EnterCriticalSection(&ProgressRenderer::s_progress);
lastPercent = i;
LeaveCriticalSection(&ProgressRenderer::s_progress);
{
std::lock_guard<std::mutex> lock(ProgressRenderer::s_progress);
lastPercent = i;
}
}
int ProgressRenderer::getCurrentPercent() {
int returnValue = 0;
EnterCriticalSection(&ProgressRenderer::s_progress);
returnValue = lastPercent;
LeaveCriticalSection(&ProgressRenderer::s_progress);
{
std::lock_guard<std::mutex> lock(ProgressRenderer::s_progress);
returnValue = lastPercent;
}
return returnValue;
}
int ProgressRenderer::getCurrentTitle() {
EnterCriticalSection(&ProgressRenderer::s_progress);
int returnValue = title;
LeaveCriticalSection(&ProgressRenderer::s_progress);
int returnValue;
{
std::lock_guard<std::mutex> lock(ProgressRenderer::s_progress);
returnValue = title;
}
return returnValue;
}
int ProgressRenderer::getCurrentStatus() {
EnterCriticalSection(&ProgressRenderer::s_progress);
int returnValue = status;
LeaveCriticalSection(&ProgressRenderer::s_progress);
int returnValue;
{
std::lock_guard<std::mutex> lock(ProgressRenderer::s_progress);
returnValue = status;
}
return returnValue;
}
ProgressRenderer::eProgressStringType ProgressRenderer::getType() {
EnterCriticalSection(&ProgressRenderer::s_progress);
eProgressStringType returnValue = m_eType;
LeaveCriticalSection(&ProgressRenderer::s_progress);
eProgressStringType returnValue;
{
std::lock_guard<std::mutex> lock(ProgressRenderer::s_progress);
returnValue = m_eType;
}
return returnValue;
}
void ProgressRenderer::setType(eProgressStringType eType) {
EnterCriticalSection(&ProgressRenderer::s_progress);
std::lock_guard<std::mutex> lock(ProgressRenderer::s_progress);
m_eType = eType;
LeaveCriticalSection(&ProgressRenderer::s_progress);
}
void ProgressRenderer::progressStage(std::wstring& wstrText) {
EnterCriticalSection(&ProgressRenderer::s_progress);
std::lock_guard<std::mutex> lock(ProgressRenderer::s_progress);
m_wstrText = wstrText;
setType(eProgressStringType_String);
LeaveCriticalSection(&ProgressRenderer::s_progress);
m_eType = eProgressStringType_String;
}
std::wstring& ProgressRenderer::getProgressString(void) {
EnterCriticalSection(&ProgressRenderer::s_progress);
std::lock_guard<std::mutex> lock(ProgressRenderer::s_progress);
std::wstring& temp = m_wstrText;
LeaveCriticalSection(&ProgressRenderer::s_progress);
return temp;
}

View file

@ -1,4 +1,5 @@
#pragma once
#include <mutex>
#include "../../../Minecraft.World/Util/ProgressListener.h"
class ProgressRenderer : public ProgressListener {
@ -9,7 +10,7 @@ public:
// on a save transfer
};
static CRITICAL_SECTION s_progress;
static std::mutex s_progress;
int getCurrentPercent();
int getCurrentTitle();

View file

@ -66,7 +66,7 @@ std::vector<CompressedTileStorage*>
GameRenderer::m_deleteStackCompressedTileStorage;
std::vector<SparseDataStorage*> GameRenderer::m_deleteStackSparseDataStorage;
#endif
CRITICAL_SECTION GameRenderer::m_csDeleteStack;
std::mutex GameRenderer::m_csDeleteStack;
ResourceLocation GameRenderer::RAIN_LOCATION =
ResourceLocation(TN_ENVIRONMENT_RAIN);
@ -170,7 +170,6 @@ GameRenderer::GameRenderer(Minecraft* mc) {
eUpdateEventCount, C4JThread::EventArray::e_modeAutoClear);
m_updateEvents->Set(eUpdateEventIsFinished);
InitializeCriticalSection(&m_csDeleteStack);
m_updateThread = new C4JThread(runUpdate, nullptr, "Chunk update");
m_updateThread->SetProcessor(CPU_CORE_CHUNK_UPDATE);
m_updateThread->Run();
@ -1045,27 +1044,27 @@ void GameRenderer::renderLevel(float a) { renderLevel(a, 0); }
#if defined(MULTITHREAD_ENABLE)
// Request that an item be deleted, when it is safe to do so
void GameRenderer::AddForDelete(uint8_t* deleteThis) {
EnterCriticalSection(&m_csDeleteStack);
m_csDeleteStack.lock();
m_deleteStackByte.push_back(deleteThis);
}
void GameRenderer::AddForDelete(SparseLightStorage* deleteThis) {
EnterCriticalSection(&m_csDeleteStack);
m_csDeleteStack.lock();
m_deleteStackSparseLightStorage.push_back(deleteThis);
}
void GameRenderer::AddForDelete(CompressedTileStorage* deleteThis) {
EnterCriticalSection(&m_csDeleteStack);
m_csDeleteStack.lock();
m_deleteStackCompressedTileStorage.push_back(deleteThis);
}
void GameRenderer::AddForDelete(SparseDataStorage* deleteThis) {
EnterCriticalSection(&m_csDeleteStack);
m_csDeleteStack.lock();
m_deleteStackSparseDataStorage.push_back(deleteThis);
}
void GameRenderer::FinishedReassigning() {
LeaveCriticalSection(&m_csDeleteStack);
m_csDeleteStack.unlock();
}
int GameRenderer::runUpdate(void* lpParam) {
@ -1124,22 +1123,24 @@ int GameRenderer::runUpdate(void* lpParam) {
// We've got stacks for things that can only safely be deleted whilst
// this thread isn't updating things - delete those things now
EnterCriticalSection(&m_csDeleteStack);
for (unsigned int i = 0; i < m_deleteStackByte.size(); i++)
delete m_deleteStackByte[i];
m_deleteStackByte.clear();
for (unsigned int i = 0; i < m_deleteStackSparseLightStorage.size();
i++)
delete m_deleteStackSparseLightStorage[i];
m_deleteStackSparseLightStorage.clear();
for (unsigned int i = 0; i < m_deleteStackCompressedTileStorage.size();
i++)
delete m_deleteStackCompressedTileStorage[i];
m_deleteStackCompressedTileStorage.clear();
for (unsigned int i = 0; i < m_deleteStackSparseDataStorage.size(); i++)
delete m_deleteStackSparseDataStorage[i];
m_deleteStackSparseDataStorage.clear();
LeaveCriticalSection(&m_csDeleteStack);
{
std::lock_guard<std::mutex> lock(m_csDeleteStack);
for (unsigned int i = 0; i < m_deleteStackByte.size(); i++)
delete m_deleteStackByte[i];
m_deleteStackByte.clear();
for (unsigned int i = 0; i < m_deleteStackSparseLightStorage.size();
i++)
delete m_deleteStackSparseLightStorage[i];
m_deleteStackSparseLightStorage.clear();
for (unsigned int i = 0;
i < m_deleteStackCompressedTileStorage.size(); i++)
delete m_deleteStackCompressedTileStorage[i];
m_deleteStackCompressedTileStorage.clear();
for (unsigned int i = 0;
i < m_deleteStackSparseDataStorage.size(); i++)
delete m_deleteStackSparseDataStorage[i];
m_deleteStackSparseDataStorage.clear();
}
// PIXEndNamedEvent();

View file

@ -9,6 +9,7 @@ class SparseLightStorage;
class CompressedTileStorage;
class SparseDataStorage;
#include <mutex>
#include "../../Minecraft.World/Util/SmoothFloat.h"
#include "../../Minecraft.World/Util/C4JThread.h"
#include "../Textures/ResourceLocation.h"
@ -191,7 +192,7 @@ public:
static std::vector<CompressedTileStorage*>
m_deleteStackCompressedTileStorage;
static std::vector<SparseDataStorage*> m_deleteStackSparseDataStorage;
static CRITICAL_SECTION m_csDeleteStack;
static std::mutex m_csDeleteStack;
static void AddForDelete(uint8_t* deleteThis);
static void AddForDelete(SparseLightStorage* deleteThis);
static void AddForDelete(CompressedTileStorage* deleteThis);

View file

@ -1,6 +1,7 @@
#include <thread>
#include <chrono>
#include <array>
#include <mutex>
#include "../Platform/stdafx.h"
#include "LevelRenderer.h"
@ -163,11 +164,7 @@ LevelRenderer::LevelRenderer(Minecraft* mc, Textures* textures) {
lastPlayerCount[i] = 0;
}
InitializeCriticalSection(&m_csDirtyChunks);
InitializeCriticalSection(&m_csRenderableTileEntities);
#if defined(_LARGE_WORLDS)
InitializeCriticalSection(&m_csChunkFlags);
#endif
// std::mutex members are default-constructed
dirtyChunkPresent = false;
lastDirtyChunkFound = 0;
@ -395,10 +392,11 @@ void LevelRenderer::setLevel(int playerIndex, MultiPlayerLevel* level) {
// actually exiting the game, so only when the primary player sets there
// level to nullptr
if (playerIndex == ProfileManager.GetPrimaryPad()) {
EnterCriticalSection(&m_csRenderableTileEntities);
renderableTileEntities.clear();
m_renderableTileEntitiesPendingRemoval.clear();
LeaveCriticalSection(&m_csRenderableTileEntities);
{
std::lock_guard<std::mutex> lock(m_csRenderableTileEntities);
renderableTileEntities.clear();
m_renderableTileEntitiesPendingRemoval.clear();
}
}
}
}
@ -428,7 +426,6 @@ void LevelRenderer::allChanged(int playerIndex) {
// to add it back then: If this CS is entered before DisableUpdateThread is
// called then (on 360 at least) we can get a deadlock when starting a game
// in splitscreen.
// EnterCriticalSection(&m_csDirtyChunks);
if (level[playerIndex] == nullptr) {
return;
}
@ -517,8 +514,6 @@ void LevelRenderer::allChanged(int playerIndex) {
Minecraft::GetInstance()->gameRenderer->EnableUpdateThread();
// 4J Stu - Remove. See comment above.
// LeaveCriticalSection(&m_csDirtyChunks);
}
void LevelRenderer::renderEntities(Vec3* cam, Culler* culler, float a) {
@ -619,21 +614,21 @@ void LevelRenderer::renderEntities(Vec3* cam, Culler* culler, float a) {
// 4J - have restructed this so that the tile entities are stored within a
// hashmap by chunk/dimension index. The index is calculated in the same way
// as the global flags.
EnterCriticalSection(&m_csRenderableTileEntities);
for (auto it = renderableTileEntities.begin();
it != renderableTileEntities.end(); it++) {
int idx = it->first;
// Don't render if it isn't in the same dimension as this player
if (!isGlobalIndexInSameDimension(idx, level[playerIndex])) continue;
{
std::lock_guard<std::mutex> lock(m_csRenderableTileEntities);
for (auto it = renderableTileEntities.begin();
it != renderableTileEntities.end(); it++) {
int idx = it->first;
// Don't render if it isn't in the same dimension as this player
if (!isGlobalIndexInSameDimension(idx, level[playerIndex])) continue;
for (auto it2 = it->second.tiles.begin();
it2 != it->second.tiles.end(); it2++) {
TileEntityRenderDispatcher::instance->render(*it2, a);
for (auto it2 = it->second.tiles.begin();
it2 != it->second.tiles.end(); it2++) {
TileEntityRenderDispatcher::instance->render(*it2, a);
}
}
}
LeaveCriticalSection(&m_csRenderableTileEntities);
mc->gameRenderer->turnOffLightLayer(a); // 4J - brought forward from 1.8.2
}
@ -653,7 +648,7 @@ std::wstring LevelRenderer::gatherStats2() {
}
void LevelRenderer::resortChunks(int xc, int yc, int zc) {
EnterCriticalSection(&m_csDirtyChunks);
std::lock_guard<std::mutex> lock(m_csDirtyChunks);
xc -= CHUNK_XZSIZE / 2;
yc -= CHUNK_SIZE / 2;
zc -= CHUNK_XZSIZE / 2;
@ -702,7 +697,6 @@ void LevelRenderer::resortChunks(int xc, int yc, int zc) {
}
}
nonStackDirtyChunksAdded();
LeaveCriticalSection(&m_csDirtyChunks);
}
int LevelRenderer::render(std::shared_ptr<LivingEntity> player, int layer,
@ -1730,7 +1724,7 @@ bool LevelRenderer::updateDirtyChunks() {
PIXAddNamedCounter(((float)memAlloc) / (1024.0f * 1024.0f),
"Command buffer allocations");
bool onlyRebuild = (memAlloc >= MAX_COMMANDBUFFER_ALLOCATIONS);
EnterCriticalSection(&m_csDirtyChunks);
std::unique_lock<std::mutex> dirtyChunksLock(m_csDirtyChunks);
// Move any dirty chunks stored in the lock free stack into global flags
int index = 0;
@ -1952,7 +1946,7 @@ bool LevelRenderer::updateDirtyChunks() {
permaChunk[index].makeCopyForRebuild(chunk);
++index;
}
LeaveCriticalSection(&m_csDirtyChunks);
dirtyChunksLock.unlock();
--index; // Bring it back into 0 counted range
@ -2043,7 +2037,7 @@ bool LevelRenderer::updateDirtyChunks() {
// this copy. The copy will then be guaranteed to be consistent
// whilst rebuilding takes place outside of that critical section.
permaChunk.makeCopyForRebuild(chunk);
LeaveCriticalSection(&m_csDirtyChunks);
dirtyChunksLock.unlock();
}
// static int64_t totalTime = 0;
// static int64_t countTime = 0;
@ -2070,7 +2064,7 @@ bool LevelRenderer::updateDirtyChunks() {
} else {
dirtyChunkPresent = false;
}
LeaveCriticalSection(&m_csDirtyChunks);
dirtyChunksLock.unlock();
return false;
}
@ -2295,7 +2289,6 @@ void LevelRenderer::setDirty(int x0, int y0, int z0, int x1, int y1, int z1,
// come from when connection is being ticked outside of normal level tick,
// and player won't be set up
if (level == nullptr) level = this->level[mc->player->GetXboxPad()];
// EnterCriticalSection(&m_csDirtyChunks);
int _x0 = Mth::intFloorDiv(x0, CHUNK_XZSIZE);
int _y0 = Mth::intFloorDiv(y0, CHUNK_SIZE);
int _z0 = Mth::intFloorDiv(z0, CHUNK_XZSIZE);
@ -2385,7 +2378,6 @@ void LevelRenderer::setDirty(int x0, int y0, int z0, int x1, int y1, int z1,
}
}
}
// LeaveCriticalSection(&m_csDirtyChunks);
}
void LevelRenderer::tileChanged(int x, int y, int z) {
@ -3687,12 +3679,9 @@ void LevelRenderer::setGlobalChunkFlags(int x, int y, int z, Level* level,
int index = getGlobalIndexForChunk(x, y, z, level);
if (index != -1) {
#if defined(_LARGE_WORLDS)
EnterCriticalSection(&m_csChunkFlags);
std::lock_guard<std::mutex> lock(m_csChunkFlags);
#endif
globalChunkFlags[index] = flags;
#if defined(_LARGE_WORLDS)
LeaveCriticalSection(&m_csChunkFlags);
#endif
}
}
@ -3702,12 +3691,9 @@ void LevelRenderer::setGlobalChunkFlag(int index, unsigned char flag,
if (index != -1) {
#if defined(_LARGE_WORLDS)
EnterCriticalSection(&m_csChunkFlags);
std::lock_guard<std::mutex> lock(m_csChunkFlags);
#endif
globalChunkFlags[index] |= sflag;
#if defined(_LARGE_WORLDS)
LeaveCriticalSection(&m_csChunkFlags);
#endif
}
}
@ -3718,12 +3704,9 @@ void LevelRenderer::setGlobalChunkFlag(int x, int y, int z, Level* level,
int index = getGlobalIndexForChunk(x, y, z, level);
if (index != -1) {
#if defined(_LARGE_WORLDS)
EnterCriticalSection(&m_csChunkFlags);
std::lock_guard<std::mutex> lock(m_csChunkFlags);
#endif
globalChunkFlags[index] |= sflag;
#if defined(_LARGE_WORLDS)
LeaveCriticalSection(&m_csChunkFlags);
#endif
}
}
@ -3747,12 +3730,9 @@ void LevelRenderer::clearGlobalChunkFlag(int x, int y, int z, Level* level,
int index = getGlobalIndexForChunk(x, y, z, level);
if (index != -1) {
#if defined(_LARGE_WORLDS)
EnterCriticalSection(&m_csChunkFlags);
std::lock_guard<std::mutex> lock(m_csChunkFlags);
#endif
globalChunkFlags[index] &= ~sflag;
#if defined(_LARGE_WORLDS)
LeaveCriticalSection(&m_csChunkFlags);
#endif
}
}
@ -3844,19 +3824,19 @@ void LevelRenderer::eraseRenderableTileEntity_Locked(
void LevelRenderer::retireRenderableTileEntitiesForChunkKey(int key) {
if (key == -1) return;
EnterCriticalSection(&m_csRenderableTileEntities);
renderableTileEntities.erase(key);
m_renderableTileEntitiesPendingRemoval.erase(key);
LeaveCriticalSection(&m_csRenderableTileEntities);
{
std::lock_guard<std::mutex> lock(m_csRenderableTileEntities);
renderableTileEntities.erase(key);
m_renderableTileEntitiesPendingRemoval.erase(key);
}
}
// 4J added
void LevelRenderer::fullyFlagRenderableTileEntitiesToBeRemoved() {
FRAME_PROFILE_SCOPE(RenderableTileEntityCleanup);
EnterCriticalSection(&m_csRenderableTileEntities);
std::lock_guard<std::mutex> lock(m_csRenderableTileEntities);
if (m_renderableTileEntitiesPendingRemoval.empty()) {
LeaveCriticalSection(&m_csRenderableTileEntities);
return;
}
@ -3886,7 +3866,6 @@ void LevelRenderer::fullyFlagRenderableTileEntitiesToBeRemoved() {
}
}
m_renderableTileEntitiesPendingRemoval.clear();
LeaveCriticalSection(&m_csRenderableTileEntities);
}
LevelRenderer::DestroyedTileManager::RecentTile::RecentTile(int x, int y, int z,
@ -3897,11 +3876,10 @@ LevelRenderer::DestroyedTileManager::RecentTile::RecentTile(int x, int y, int z,
}
LevelRenderer::DestroyedTileManager::DestroyedTileManager() {
InitializeCriticalSection(&m_csDestroyedTiles);
// std::mutex is default-constructed
}
LevelRenderer::DestroyedTileManager::~DestroyedTileManager() {
DeleteCriticalSection(&m_csDestroyedTiles);
for (unsigned int i = 0; i < m_destroyedTiles.size(); i++) {
delete m_destroyedTiles[i];
}
@ -3911,7 +3889,7 @@ LevelRenderer::DestroyedTileManager::~DestroyedTileManager() {
// be called before it actually is)
void LevelRenderer::DestroyedTileManager::destroyingTileAt(Level* level, int x,
int y, int z) {
EnterCriticalSection(&m_csDestroyedTiles);
std::lock_guard<std::mutex> lock(m_csDestroyedTiles);
// Store a list of AABBs that the tile to be destroyed would have made,
// before we go and destroy it. This is made slightly more complicated as
@ -3928,8 +3906,6 @@ void LevelRenderer::DestroyedTileManager::destroyingTileAt(Level* level, int x,
}
m_destroyedTiles.push_back(recentTile);
LeaveCriticalSection(&m_csDestroyedTiles);
}
// For chunk rebuilding to inform the manager that a chunk (a 16x16x16 tile
@ -3937,7 +3913,7 @@ void LevelRenderer::DestroyedTileManager::destroyingTileAt(Level* level, int x,
void LevelRenderer::DestroyedTileManager::updatedChunkAt(Level* level, int x,
int y, int z,
int veryNearCount) {
EnterCriticalSection(&m_csDestroyedTiles);
std::lock_guard<std::mutex> lock(m_csDestroyedTiles);
// There's 2 stages to this. This function is called when a renderer chunk
// has been rebuilt, but that chunk's render data might be grouped
@ -3979,15 +3955,13 @@ void LevelRenderer::DestroyedTileManager::updatedChunkAt(Level* level, int x,
}
}
}
LeaveCriticalSection(&m_csDestroyedTiles);
}
// For game to get any AABBs that the user should be colliding with as render
// data has not yet been updated
void LevelRenderer::DestroyedTileManager::addAABBs(Level* level, AABB* box,
AABBList* boxes) {
EnterCriticalSection(&m_csDestroyedTiles);
std::lock_guard<std::mutex> lock(m_csDestroyedTiles);
for (unsigned int i = 0; i < m_destroyedTiles.size(); i++) {
if (m_destroyedTiles[i]->level == level) {
@ -4009,11 +3983,10 @@ void LevelRenderer::DestroyedTileManager::addAABBs(Level* level, AABB* box,
}
}
LeaveCriticalSection(&m_csDestroyedTiles);
}
void LevelRenderer::DestroyedTileManager::tick() {
EnterCriticalSection(&m_csDestroyedTiles);
std::lock_guard<std::mutex> lock(m_csDestroyedTiles);
// Remove any tiles that have timed out
for (unsigned int i = 0; i < m_destroyedTiles.size();) {
@ -4025,8 +3998,6 @@ void LevelRenderer::DestroyedTileManager::tick() {
i++;
}
}
LeaveCriticalSection(&m_csDestroyedTiles);
}
#if defined(_LARGE_WORLDS)

View file

@ -8,6 +8,7 @@
#include <xmcore.h>
#endif
#include <unordered_set>
#include <mutex>
class MultiPlayerLevel;
class Textures;
class Chunk;
@ -164,7 +165,7 @@ private:
typedef std::unordered_map<int, rtePendingRemovalSet, IntKeyHash, IntKeyEq>
rtePendingRemovalMap;
rtePendingRemovalMap m_renderableTileEntitiesPendingRemoval;
CRITICAL_SECTION m_csRenderableTileEntities;
std::mutex m_csRenderableTileEntities;
MultiPlayerLevel* level[4]; // 4J - now one per player
Textures* textures;
// std::vector<Chunk *> *sortedChunks[4]; // 4J - removed - not
@ -215,7 +216,7 @@ private:
public:
void fullyFlagRenderableTileEntitiesToBeRemoved(); // 4J added
CRITICAL_SECTION m_csDirtyChunks;
std::mutex m_csDirtyChunks;
bool m_nearDirtyChunk;
// 4J - Destroyed Tile Management - these things added so we can track tiles
@ -235,7 +236,7 @@ public:
RecentTile(int x, int y, int z, Level* level);
~RecentTile() = default;
};
CRITICAL_SECTION m_csDestroyedTiles;
std::mutex m_csDestroyedTiles;
std::vector<RecentTile*> m_destroyedTiles;
public:
@ -343,7 +344,7 @@ public:
static void staticCtor();
static int rebuildChunkThreadProc(void* lpParam);
CRITICAL_SECTION m_csChunkFlags;
std::mutex m_csChunkFlags;
#endif
void nonStackDirtyChunksAdded();

View file

@ -777,11 +777,11 @@ int ConsoleSaveFileOriginal::getOriginalSaveVersion() {
}
void ConsoleSaveFileOriginal::LockSaveAccess() {
EnterCriticalSection(&m_lock);
m_lock.lock();
}
void ConsoleSaveFileOriginal::ReleaseSaveAccess() {
LeaveCriticalSection(&m_lock);
m_lock.unlock();
}
ESavePlatform ConsoleSaveFileOriginal::getSavePlatform() {

View file

@ -1,4 +1,5 @@
#pragma once
#include <mutex>
#include "FileHeader.h"
#include "ConsoleSavePath.h"
@ -23,7 +24,7 @@ private:
#endif
void* pvSaveMem;
CRITICAL_SECTION m_lock;
std::mutex m_lock;
void PrepareForWrite(FileEntry* file, unsigned int nNumberOfBytesToWrite);
void MoveDataBeyond(FileEntry* file, unsigned int nNumberOfBytesToWrite);

View file

@ -397,7 +397,6 @@ ConsoleSaveFileSplit::ConsoleSaveFileSplit(ConsoleSaveFile* sourceSave,
void ConsoleSaveFileSplit::_init(const std::wstring& fileName, void* pvSaveData,
unsigned int fileSize, ESavePlatform plat) {
InitializeCriticalSectionAndSpinCount(&m_lock, 5120);
m_lastTickTime = 0;
@ -550,7 +549,6 @@ ConsoleSaveFileSplit::~ConsoleSaveFileSplit() {
}
StorageManager.ResetSubfiles();
DeleteCriticalSection(&m_lock);
}
// Add the file to our table of internal files if not already there
@ -1508,10 +1506,10 @@ int ConsoleSaveFileSplit::getOriginalSaveVersion() {
return header.getOriginalSaveVersion();
}
void ConsoleSaveFileSplit::LockSaveAccess() { EnterCriticalSection(&m_lock); }
void ConsoleSaveFileSplit::LockSaveAccess() { m_lock.lock(); }
void ConsoleSaveFileSplit::ReleaseSaveAccess() {
LeaveCriticalSection(&m_lock);
m_lock.unlock();
}
ESavePlatform ConsoleSaveFileSplit::getSavePlatform() {

View file

@ -1,4 +1,5 @@
#pragma once
#include <mutex>
#include "FileHeader.h"
#include "ConsoleSavePath.h"
@ -79,7 +80,7 @@ private:
#endif
void* pvSaveMem;
CRITICAL_SECTION m_lock;
std::mutex m_lock;
void PrepareForWrite(FileEntry* file, unsigned int nNumberOfBytesToWrite);
void MoveDataBeyond(FileEntry* file, unsigned int nNumberOfBytesToWrite);

View file

@ -41,7 +41,7 @@ Compression* Compression::getCompression() {
int32_t Compression::CompressLZXRLE(void* pDestination, unsigned int* pDestSize,
void* pSource, unsigned int SrcSize) {
EnterCriticalSection(&rleCompressLock);
std::lock_guard<std::mutex> lock(rleCompressLock);
// static unsigned char rleBuf[1024*100];
unsigned char* pucIn = (unsigned char*)pSource;
@ -83,7 +83,6 @@ int32_t Compression::CompressLZXRLE(void* pDestination, unsigned int* pDestSize,
PIXBeginNamedEvent(0, "Secondary compression");
Compress(pDestination, pDestSize, rleCompressBuf, rleSize);
PIXEndNamedEvent();
LeaveCriticalSection(&rleCompressLock);
// printf("Compressed from %d to %d to %d\n",SrcSize,rleSize,*pDestSize);
return S_OK;
@ -91,7 +90,8 @@ int32_t Compression::CompressLZXRLE(void* pDestination, unsigned int* pDestSize,
int32_t Compression::CompressRLE(void* pDestination, unsigned int* pDestSize,
void* pSource, unsigned int SrcSize) {
EnterCriticalSection(&rleCompressLock);
unsigned int rleSize;
{ std::lock_guard<std::mutex> lock(rleCompressLock);
// static unsigned char rleBuf[1024*100];
unsigned char* pucIn = (unsigned char*)pSource;
@ -127,9 +127,9 @@ int32_t Compression::CompressRLE(void* pDestination, unsigned int* pDestSize,
*pucOut++ = thisOne;
}
} while (pucIn != pucEnd);
unsigned int rleSize = (unsigned int)(pucOut - rleCompressBuf);
rleSize = (unsigned int)(pucOut - rleCompressBuf);
PIXEndNamedEvent();
LeaveCriticalSection(&rleCompressLock);
}
// Return
if (rleSize <= *pDestSize) {
@ -147,7 +147,7 @@ int32_t Compression::CompressRLE(void* pDestination, unsigned int* pDestSize,
int32_t Compression::DecompressLZXRLE(void* pDestination,
unsigned int* pDestSize, void* pSource,
unsigned int SrcSize) {
EnterCriticalSection(&rleDecompressLock);
std::lock_guard<std::mutex> lock(rleDecompressLock);
// 4J Stu - Fix for #13676 - Crash: Crash while attempting to load a world
// after updating TU Some saves can have chunks that decompress into very
// large sizes, so I have doubled the size of this buffer Ideally we should
@ -203,13 +203,12 @@ int32_t Compression::DecompressLZXRLE(void* pDestination,
if (dynamicRleBuf != nullptr) delete[] dynamicRleBuf;
LeaveCriticalSection(&rleDecompressLock);
return S_OK;
}
int32_t Compression::DecompressRLE(void* pDestination, unsigned int* pDestSize,
void* pSource, unsigned int SrcSize) {
EnterCriticalSection(&rleDecompressLock);
std::lock_guard<std::mutex> lock(rleDecompressLock);
// unsigned char *pucIn = (unsigned char *)rleDecompressBuf;
unsigned char* pucIn = (unsigned char*)pSource;
@ -238,7 +237,6 @@ int32_t Compression::DecompressRLE(void* pDestination, unsigned int* pDestSize,
}
*pDestSize = (unsigned int)(pucOut - (unsigned char*)pDestination);
LeaveCriticalSection(&rleDecompressLock);
return S_OK;
}
@ -439,17 +437,12 @@ Compression::Compression() {
m_localDecompressType = eCompressionType_ZLIBRLE;
m_decompressType = m_localDecompressType;
InitializeCriticalSection(&rleCompressLock);
InitializeCriticalSection(&rleDecompressLock);
}
Compression::~Compression() {
XMemDestroyCompressionContext(compressionContext);
XMemDestroyDecompressionContext(decompressionContext);
DeleteCriticalSection(&rleCompressLock);
DeleteCriticalSection(&rleDecompressLock);
}
void Compression::SetDecompressionType(ESavePlatform platform) {

View file

@ -1,4 +1,5 @@
#pragma once
#include <mutex>
#include "../Files/FileHeader.h"
class Compression {
@ -67,8 +68,8 @@ private:
XMEMCOMPRESSION_CONTEXT compressionContext;
XMEMDECOMPRESSION_CONTEXT decompressionContext;
CRITICAL_SECTION rleCompressLock;
CRITICAL_SECTION rleDecompressLock;
std::mutex rleCompressLock;
std::mutex rleDecompressLock;
unsigned char rleCompressBuf[1024 * 100];
static const unsigned int staticRleSize = 1024 * 200;

View file

@ -27,6 +27,7 @@
#include "../Util/WeighedRandom.h"
#include "../IO/Files/ConsoleSaveFile.h"
#include <mutex>
#include <xuiapp.h>
#include "../../Minecraft.Client/Minecraft.h"
#include "../../Minecraft.Client/Rendering/LevelRenderer.h"
@ -539,17 +540,12 @@ void Level::_init() {
isClientSide = false;
InitializeCriticalSection(&m_entitiesCS);
InitializeCriticalSection(&m_tileEntityListCS);
updatingTileEntities = false;
villageSiege = new VillageSiege(this);
scoreboard = new Scoreboard();
toCheckLevel = new int[32 * 32 * 32]; // 4J - brought forward from 1.8.2
InitializeCriticalSectionAndSpinCount(
&m_checkLightCS, 5120); // 4J - added for 1.8.2 lighting
// 4J Added
m_bDisableAddNewTileEntities = false;
@ -699,16 +695,11 @@ Level::~Level() {
NotGateTile::removeLevelReferences(this); // 4J added
}
DeleteCriticalSection(&m_checkLightCS);
// 4J-PB - savedDataStorage is shared between overworld and nether levels in
// the server, so it will already have been deleted on the first level
// delete
if (savedDataStorage != nullptr) delete savedDataStorage;
DeleteCriticalSection(&m_entitiesCS);
DeleteCriticalSection(&m_tileEntityListCS);
// 4J Stu - At least one of the listeners is something we cannot delete, the
// LevelRenderer
/*
@ -1622,11 +1613,11 @@ bool Level::addEntity(std::shared_ptr<Entity> e) {
MemSect(42);
getChunk(xc, zc)->addEntity(e);
MemSect(0);
EnterCriticalSection(&m_entitiesCS);
{ std::lock_guard<std::recursive_mutex> lock(m_entitiesCS);
MemSect(43);
entities.push_back(e);
MemSect(0);
LeaveCriticalSection(&m_entitiesCS);
}
MemSect(44);
entityAdded(e);
MemSect(0);
@ -1707,7 +1698,7 @@ void Level::removeEntityImmediately(std::shared_ptr<Entity> e) {
getChunk(xc, zc)->removeEntity(e);
}
EnterCriticalSection(&m_entitiesCS);
{ std::lock_guard<std::recursive_mutex> lock(m_entitiesCS);
std::vector<std::shared_ptr<Entity> >::iterator it = entities.begin();
std::vector<std::shared_ptr<Entity> >::iterator endIt = entities.end();
while (it != endIt && *it != e) it++;
@ -1715,7 +1706,7 @@ void Level::removeEntityImmediately(std::shared_ptr<Entity> e) {
if (it != endIt) {
entities.erase(it);
}
LeaveCriticalSection(&m_entitiesCS);
}
entityRemoved(e);
}
@ -2084,7 +2075,7 @@ void Level::tickEntities() {
}
}
EnterCriticalSection(&m_entitiesCS);
{ std::lock_guard<std::recursive_mutex> lock(m_entitiesCS);
for (auto it = entities.begin(); it != entities.end();) {
bool found = false;
@ -2101,7 +2092,7 @@ void Level::tickEntities() {
it++;
}
}
LeaveCriticalSection(&m_entitiesCS);
}
auto itETREnd = entitiesToRemove.end();
for (auto it = entitiesToRemove.begin(); it != itETREnd; it++) {
@ -2125,7 +2116,7 @@ void Level::tickEntities() {
/* 4J Jev, using an iterator causes problems here as
* the vector is modified from inside this loop.
*/
EnterCriticalSection(&m_entitiesCS);
{ std::lock_guard<std::recursive_mutex> lock(m_entitiesCS);
for (unsigned int i = 0; i < entities.size();) {
std::shared_ptr<Entity> e = entities.at(i);
@ -2171,9 +2162,9 @@ void Level::tickEntities() {
i++;
}
}
LeaveCriticalSection(&m_entitiesCS);
}
EnterCriticalSection(&m_tileEntityListCS);
{ std::lock_guard<std::recursive_mutex> lock(m_tileEntityListCS);
updatingTileEntities = true;
for (auto it = tileEntityList.begin(); it != tileEntityList.end();) {
@ -2243,12 +2234,12 @@ void Level::tickEntities() {
}
pendingTileEntities.clear();
}
LeaveCriticalSection(&m_tileEntityListCS);
}
}
void Level::addAllPendingTileEntities(
std::vector<std::shared_ptr<TileEntity> >& entities) {
EnterCriticalSection(&m_tileEntityListCS);
{ std::lock_guard<std::recursive_mutex> lock(m_tileEntityListCS);
if (updatingTileEntities) {
for (auto it = entities.begin(); it != entities.end(); it++) {
pendingTileEntities.push_back(*it);
@ -2258,7 +2249,7 @@ void Level::addAllPendingTileEntities(
tileEntityList.push_back(*it);
}
}
LeaveCriticalSection(&m_tileEntityListCS);
}
}
void Level::tick(std::shared_ptr<Entity> e) { tick(e, true); }
@ -2598,9 +2589,9 @@ return shared_ptr<Entity>();
std::wstring Level::gatherStats() {
wchar_t buf[64];
EnterCriticalSection(&m_entitiesCS);
{ std::lock_guard<std::recursive_mutex> lock(m_entitiesCS);
swprintf(buf, 64, L"All:%d", entities.size());
LeaveCriticalSection(&m_entitiesCS);
}
return std::wstring(buf);
}
@ -2615,7 +2606,7 @@ std::shared_ptr<TileEntity> Level::getTileEntity(int x, int y, int z) {
std::shared_ptr<TileEntity> tileEntity = nullptr;
if (updatingTileEntities) {
EnterCriticalSection(&m_tileEntityListCS);
{ std::lock_guard<std::recursive_mutex> lock(m_tileEntityListCS);
for (int i = 0; i < pendingTileEntities.size(); i++) {
std::shared_ptr<TileEntity> e = pendingTileEntities.at(i);
if (!e->isRemoved() && e->x == x && e->y == y && e->z == z) {
@ -2623,7 +2614,7 @@ std::shared_ptr<TileEntity> Level::getTileEntity(int x, int y, int z) {
break;
}
}
LeaveCriticalSection(&m_tileEntityListCS);
}
}
if (tileEntity == nullptr) {
@ -2634,7 +2625,7 @@ std::shared_ptr<TileEntity> Level::getTileEntity(int x, int y, int z) {
}
if (tileEntity == nullptr) {
EnterCriticalSection(&m_tileEntityListCS);
{ std::lock_guard<std::recursive_mutex> lock(m_tileEntityListCS);
for (auto it = pendingTileEntities.begin();
it != pendingTileEntities.end(); it++) {
std::shared_ptr<TileEntity> e = *it;
@ -2644,7 +2635,7 @@ std::shared_ptr<TileEntity> Level::getTileEntity(int x, int y, int z) {
break;
}
}
LeaveCriticalSection(&m_tileEntityListCS);
}
}
return tileEntity;
}
@ -2652,7 +2643,7 @@ std::shared_ptr<TileEntity> Level::getTileEntity(int x, int y, int z) {
void Level::setTileEntity(int x, int y, int z,
std::shared_ptr<TileEntity> tileEntity) {
if (tileEntity != nullptr && !tileEntity->isRemoved()) {
EnterCriticalSection(&m_tileEntityListCS);
{ std::lock_guard<std::recursive_mutex> lock(m_tileEntityListCS);
if (updatingTileEntities) {
tileEntity->x = x;
tileEntity->y = y;
@ -2677,12 +2668,12 @@ void Level::setTileEntity(int x, int y, int z,
LevelChunk* lc = getChunk(x >> 4, z >> 4);
if (lc != nullptr) lc->setTileEntity(x & 15, y, z & 15, tileEntity);
}
LeaveCriticalSection(&m_tileEntityListCS);
}
}
}
void Level::removeTileEntity(int x, int y, int z) {
EnterCriticalSection(&m_tileEntityListCS);
{ std::lock_guard<std::recursive_mutex> lock(m_tileEntityListCS);
std::shared_ptr<TileEntity> te = getTileEntity(x, y, z);
if (te != nullptr && updatingTileEntities) {
te->setRemoved();
@ -2707,13 +2698,13 @@ void Level::removeTileEntity(int x, int y, int z) {
LevelChunk* lc = getChunk(x >> 4, z >> 4);
if (lc != nullptr) lc->removeTileEntity(x & 15, y, z & 15);
}
LeaveCriticalSection(&m_tileEntityListCS);
}
}
void Level::markForRemoval(std::shared_ptr<TileEntity> entity) {
EnterCriticalSection(&m_tileEntityListCS);
{ std::lock_guard<std::recursive_mutex> lock(m_tileEntityListCS);
tileEntitiesToUnload.insert(entity);
LeaveCriticalSection(&m_tileEntityListCS);
}
}
bool Level::isSolidRenderTile(int x, int y, int z) {
@ -3110,7 +3101,7 @@ void Level::checkLight(LightLayer::variety layer, int xc, int yc, int zc,
}
EnterCriticalSection(&m_checkLightCS);
{ std::lock_guard<std::recursive_mutex> lock(m_checkLightCS);
initCachePartial(cache, xc, yc, zc);
@ -3133,7 +3124,6 @@ void Level::checkLight(LightLayer::variety layer, int xc, int yc, int zc,
int minXZ = -(dimension->getXZSize() * 16) / 2;
int maxXZ = (dimension->getXZSize() * 16) / 2 - 1;
if ((xc > maxXZ) || (xc < minXZ) || (zc > maxXZ) || (zc < minXZ)) {
LeaveCriticalSection(&m_checkLightCS);
return;
}
@ -3338,7 +3328,7 @@ void Level::checkLight(LightLayer::variety layer, int xc, int yc, int zc,
// if( cache ) XUnlockL2(XLOCKL2_INDEX_TITLE);
flushCache(cache, cacheUse, layer);
LeaveCriticalSection(&m_checkLightCS);
}
}
bool Level::tickPendingTicks(bool force) { return false; }
@ -3423,9 +3413,8 @@ std::shared_ptr<Entity> Level::getClosestEntityOfClass(
}
std::vector<std::shared_ptr<Entity> > Level::getAllEntities() {
EnterCriticalSection(&m_entitiesCS);
std::lock_guard<std::recursive_mutex> lock(m_entitiesCS);
std::vector<std::shared_ptr<Entity> > retVec = entities;
LeaveCriticalSection(&m_entitiesCS);
return retVec;
}
@ -3447,7 +3436,7 @@ unsigned int Level::countInstanceOf(
unsigned int count = 0;
if (protectedCount) *protectedCount = 0;
if (couldWanderCount) *couldWanderCount = 0;
EnterCriticalSection(&m_entitiesCS);
{ std::lock_guard<std::recursive_mutex> lock(m_entitiesCS);
auto itEnd = entities.end();
for (auto it = entities.begin(); it != itEnd; it++) {
std::shared_ptr<Entity> e = *it; // entities.at(i);
@ -3467,7 +3456,7 @@ unsigned int Level::countInstanceOf(
if (e->instanceof(clas)) count++;
}
}
LeaveCriticalSection(&m_entitiesCS);
}
return count;
}
@ -3475,7 +3464,7 @@ unsigned int Level::countInstanceOf(
unsigned int Level::countInstanceOfInRange(eINSTANCEOF clas, bool singleType,
int range, int x, int y, int z) {
unsigned int count = 0;
EnterCriticalSection(&m_entitiesCS);
{ std::lock_guard<std::recursive_mutex> lock(m_entitiesCS);
auto itEnd = entities.end();
for (auto it = entities.begin(); it != itEnd; it++) {
std::shared_ptr<Entity> e = *it; // entities.at(i);
@ -3493,14 +3482,14 @@ unsigned int Level::countInstanceOfInRange(eINSTANCEOF clas, bool singleType,
if (e->instanceof(clas)) count++;
}
}
LeaveCriticalSection(&m_entitiesCS);
}
return count;
}
void Level::addEntities(std::vector<std::shared_ptr<Entity> >* list) {
// entities.addAll(list);
EnterCriticalSection(&m_entitiesCS);
{ std::lock_guard<std::recursive_mutex> lock(m_entitiesCS);
entities.insert(entities.end(), list->begin(), list->end());
auto itEnd = list->end();
bool deleteDragons = false;
@ -3528,7 +3517,7 @@ void Level::addEntities(std::vector<std::shared_ptr<Entity> >* list) {
}
}
}
LeaveCriticalSection(&m_entitiesCS);
}
}
void Level::removeEntities(std::vector<std::shared_ptr<Entity> >* list) {
@ -3943,11 +3932,11 @@ void Level::ensureAdded(std::shared_ptr<Entity> entity) {
}
// if (!entities.contains(entity))
EnterCriticalSection(&m_entitiesCS);
{ std::lock_guard<std::recursive_mutex> lock(m_entitiesCS);
if (find(entities.begin(), entities.end(), entity) == entities.end()) {
entities.push_back(entity);
}
LeaveCriticalSection(&m_entitiesCS);
}
}
bool Level::mayInteract(std::shared_ptr<Player> player, int xt, int yt, int zt,

View file

@ -10,6 +10,7 @@
#include "../WorldGen/Biomes/Biome.h"
#include "../Util/C4JThread.h"
#include <cstdint>
#include <mutex>
#include <unordered_set>
// 4J Stu - This value should be big enough that we don't get any crashes causes
@ -100,7 +101,7 @@ public:
static const int TICKS_PER_DAY = 20 * 60 * 20; // ORG:20*60*20
public:
CRITICAL_SECTION m_entitiesCS; // 4J added
std::recursive_mutex m_entitiesCS; // 4J added
std::vector<std::shared_ptr<Entity> > entities;
@ -110,7 +111,7 @@ protected:
public:
bool hasEntitiesToRemove(); // 4J added
bool m_bDisableAddNewTileEntities; // 4J Added
CRITICAL_SECTION m_tileEntityListCS; // 4J added
std::recursive_mutex m_tileEntityListCS; // 4J added
std::vector<std::shared_ptr<TileEntity> > tileEntityList;
private:
@ -630,7 +631,7 @@ public:
virtual bool newFallingTileAllowed() { return true; }
// 4J - added for new lighting from 1.8.2
CRITICAL_SECTION m_checkLightCS;
std::recursive_mutex m_checkLightCS;
private:
int m_iHighestY; // 4J-PB - for the end portal in The End

View file

@ -19,29 +19,25 @@
#include "../Entities/ItemEntity.h"
#include "../Entities/Mobs/Minecart.h"
#include <mutex>
#if defined(SHARING_ENABLED)
CRITICAL_SECTION LevelChunk::m_csSharing;
std::mutex LevelChunk::m_csSharing;
#endif
#if defined(_ENTITIES_RW_SECTION)
// AP - use a RW critical section so we can have multiple threads reading the
// same data to avoid a clash
CRITICAL_RW_SECTION LevelChunk::m_csEntities;
#else
CRITICAL_SECTION LevelChunk::m_csEntities;
std::mutex LevelChunk::m_csEntities;
#endif
CRITICAL_SECTION LevelChunk::m_csTileEntities;
std::mutex LevelChunk::m_csTileEntities;
bool LevelChunk::touchedSky = false;
void LevelChunk::staticCtor() {
#if defined(SHARING_ENABLED)
InitializeCriticalSection(&m_csSharing);
#endif
#if defined(_ENTITIES_RW_SECTION)
InitializeCriticalRWSection(&m_csEntities);
#else
InitializeCriticalSection(&m_csEntities);
#endif
InitializeCriticalSection(&m_csTileEntities);
}
void LevelChunk::init(Level* level, int x, int z) {
@ -52,14 +48,14 @@ void LevelChunk::init(Level* level, int x, int z) {
#if defined(_ENTITIES_RW_SECTION)
EnterCriticalRWSection(&m_csEntities, true);
#else
EnterCriticalSection(&m_csEntities);
{ std::lock_guard<std::mutex> lock(m_csEntities);
#endif
entityBlocks =
new std::vector<std::shared_ptr<Entity> >*[ENTITY_BLOCKS_LENGTH];
#if defined(_ENTITIES_RW_SECTION)
LeaveCriticalRWSection(&m_csEntities, true);
#else
LeaveCriticalSection(&m_csEntities);
}
#endif
terrainPopulated = 0;
@ -83,7 +79,7 @@ void LevelChunk::init(Level* level, int x, int z) {
#if defined(_ENTITIES_RW_SECTION)
EnterCriticalRWSection(&m_csEntities, true);
#else
EnterCriticalSection(&m_csEntities);
{ std::lock_guard<std::mutex> lock(m_csEntities);
#endif
for (int i = 0; i < ENTITY_BLOCKS_LENGTH; i++) {
entityBlocks[i] = new std::vector<std::shared_ptr<Entity> >();
@ -91,7 +87,7 @@ void LevelChunk::init(Level* level, int x, int z) {
#if defined(_ENTITIES_RW_SECTION)
LeaveCriticalRWSection(&m_csEntities, true);
#else
LeaveCriticalSection(&m_csEntities);
}
#endif
MemSect(0);
@ -253,10 +249,9 @@ void LevelChunk::setUnsaved(bool unsaved) {
void LevelChunk::stopSharingTilesAndData() {
#if defined(SHARING_ENABLED)
EnterCriticalSection(&m_csSharing);
{ std::lock_guard<std::mutex> lock(m_csSharing);
lastUnsharedTime = System::currentTimeMillis();
if (!sharingTilesAndData) {
LeaveCriticalSection(&m_csSharing);
return;
}
@ -269,7 +264,6 @@ void LevelChunk::stopSharingTilesAndData() {
if ((serverTerrainPopulated) &&
(((*serverTerrainPopulated) & sTerrainPopulatedAllAffecting) !=
sTerrainPopulatedAllAffecting)) {
LeaveCriticalSection(&m_csSharing);
return;
}
@ -277,7 +271,6 @@ void LevelChunk::stopSharingTilesAndData() {
// don't drop out here we'll end up unsharing the chunk at this location for
// no reason
if (isEmpty()) {
LeaveCriticalSection(&m_csSharing);
return;
}
@ -311,7 +304,7 @@ void LevelChunk::stopSharingTilesAndData() {
sharingTilesAndData = false;
MemSect(0);
LeaveCriticalSection(&m_csSharing);
}
#endif
}
@ -322,10 +315,9 @@ void LevelChunk::stopSharingTilesAndData() {
// not sharing
void LevelChunk::reSyncLighting() {
#if defined(SHARING_ENABLED)
EnterCriticalSection(&m_csSharing);
{ std::lock_guard<std::mutex> lock(m_csSharing);
if (isEmpty()) {
LeaveCriticalSection(&m_csSharing);
return;
}
@ -354,15 +346,14 @@ void LevelChunk::reSyncLighting() {
upperBlockLight = new SparseLightStorage(lc->upperBlockLight);
GameRenderer::FinishedReassigning();
}
LeaveCriticalSection(&m_csSharing);
}
#endif
}
void LevelChunk::startSharingTilesAndData(int forceMs) {
#if defined(SHARING_ENABLED)
EnterCriticalSection(&m_csSharing);
{ std::lock_guard<std::mutex> lock(m_csSharing);
if (sharingTilesAndData) {
LeaveCriticalSection(&m_csSharing);
return;
}
@ -371,7 +362,6 @@ void LevelChunk::startSharingTilesAndData(int forceMs) {
// doesn't make sense to go resharing the 0,0 block on behalf of an empty
// chunk either
if (isEmpty()) {
LeaveCriticalSection(&m_csSharing);
return;
}
@ -394,7 +384,6 @@ void LevelChunk::startSharingTilesAndData(int forceMs) {
if (!lowerBlocks->isSameAs(lc->lowerBlocks) ||
(upperBlocks && lc->upperBlocks &&
!upperBlocks->isSameAs(lc->upperBlocks))) {
LeaveCriticalSection(&m_csSharing);
return;
}
} else {
@ -402,7 +391,6 @@ void LevelChunk::startSharingTilesAndData(int forceMs) {
// last wanted to unshare this chunk
int64_t timenow = System::currentTimeMillis();
if ((timenow - lastUnsharedTime) < forceMs) {
LeaveCriticalSection(&m_csSharing);
return;
}
}
@ -429,7 +417,7 @@ void LevelChunk::startSharingTilesAndData(int forceMs) {
}
sharingTilesAndData = true;
LeaveCriticalSection(&m_csSharing);
}
#endif
}
@ -1193,13 +1181,13 @@ void LevelChunk::addEntity(std::shared_ptr<Entity> e) {
#if defined(_ENTITIES_RW_SECTION)
EnterCriticalRWSection(&m_csEntities, true);
#else
EnterCriticalSection(&m_csEntities);
{ std::lock_guard<std::mutex> lock(m_csEntities);
#endif
entityBlocks[yc]->push_back(e);
#if defined(_ENTITIES_RW_SECTION)
LeaveCriticalRWSection(&m_csEntities, true);
#else
LeaveCriticalSection(&m_csEntities);
}
#endif
}
@ -1214,7 +1202,7 @@ void LevelChunk::removeEntity(std::shared_ptr<Entity> e, int yc) {
#if defined(_ENTITIES_RW_SECTION)
EnterCriticalRWSection(&m_csEntities, true);
#else
EnterCriticalSection(&m_csEntities);
{ std::lock_guard<std::mutex> lock(m_csEntities);
#endif
// 4J - was entityBlocks[yc]->remove(e);
@ -1231,7 +1219,7 @@ void LevelChunk::removeEntity(std::shared_ptr<Entity> e, int yc) {
#if defined(_ENTITIES_RW_SECTION)
LeaveCriticalRWSection(&m_csEntities, true);
#else
LeaveCriticalSection(&m_csEntities);
}
#endif
}
@ -1256,14 +1244,13 @@ std::shared_ptr<TileEntity> LevelChunk::getTileEntity(int x, int y, int z) {
// 4J Stu - Changed as we should not be using the [] accessor (causes an
// insert when we don't want one)
// shared_ptr<TileEntity> tileEntity = tileEntities[pos];
EnterCriticalSection(&m_csTileEntities);
std::shared_ptr<TileEntity> tileEntity = nullptr;
{ std::unique_lock<std::mutex> lock(m_csTileEntities);
auto it = tileEntities.find(pos);
if (it == tileEntities.end()) {
LeaveCriticalSection(
&m_csTileEntities); // Note: don't assume iterator is valid for
// tileEntities after this point
lock.unlock(); // Note: don't assume iterator is valid for
// tileEntities after this point
// Fix for #48450 - All: Code Defect: Hang: Game hangs in tutorial, when
// player arrive at the particular coordinate 4J Stu - Chests try to get
@ -1289,20 +1276,20 @@ std::shared_ptr<TileEntity> LevelChunk::getTileEntity(int x, int y, int z) {
// doesn't seem right - assignment wrong way? Check
// 4J Stu - It should have been inserted by now, but check to be sure
EnterCriticalSection(&m_csTileEntities);
{ std::lock_guard<std::mutex> lock2(m_csTileEntities);
auto newIt = tileEntities.find(pos);
if (newIt != tileEntities.end()) {
tileEntity = newIt->second;
}
LeaveCriticalSection(&m_csTileEntities);
}
} else {
tileEntity = it->second;
LeaveCriticalSection(&m_csTileEntities);
}
}
if (tileEntity != nullptr && tileEntity->isRemoved()) {
EnterCriticalSection(&m_csTileEntities);
{ std::lock_guard<std::mutex> lock(m_csTileEntities);
tileEntities.erase(pos);
LeaveCriticalSection(&m_csTileEntities);
}
return nullptr;
}
@ -1315,9 +1302,10 @@ void LevelChunk::addTileEntity(std::shared_ptr<TileEntity> te) {
int zz = (int)(te->z - this->z * 16);
setTileEntity(xx, yy, zz, te);
if (loaded) {
EnterCriticalSection(&level->m_tileEntityListCS);
level->tileEntityList.push_back(te);
LeaveCriticalSection(&level->m_tileEntityListCS);
{
std::lock_guard<std::recursive_mutex> lock(level->m_tileEntityListCS);
level->tileEntityList.push_back(te);
}
}
}
@ -1345,9 +1333,9 @@ void LevelChunk::setTileEntity(int x, int y, int z,
tileEntity->clearRemoved();
EnterCriticalSection(&m_csTileEntities);
{ std::lock_guard<std::mutex> lock(m_csTileEntities);
tileEntities[pos] = tileEntity;
LeaveCriticalSection(&m_csTileEntities);
}
}
void LevelChunk::removeTileEntity(int x, int y, int z) {
@ -1359,7 +1347,7 @@ void LevelChunk::removeTileEntity(int x, int y, int z) {
// if (removeThis != null) {
// removeThis.setRemoved();
// }
EnterCriticalSection(&m_csTileEntities);
{ std::lock_guard<std::mutex> lock(m_csTileEntities);
auto it = tileEntities.find(pos);
if (it != tileEntities.end()) {
std::shared_ptr<TileEntity> te = tileEntities[pos];
@ -1372,7 +1360,7 @@ void LevelChunk::removeTileEntity(int x, int y, int z) {
te->setRemoved();
}
}
LeaveCriticalSection(&m_csTileEntities);
}
}
}
@ -1417,18 +1405,18 @@ void LevelChunk::load() {
#endif
std::vector<std::shared_ptr<TileEntity> > values;
EnterCriticalSection(&m_csTileEntities);
{ std::lock_guard<std::mutex> lock(m_csTileEntities);
for (auto it = tileEntities.begin(); it != tileEntities.end();
it++) {
values.push_back(it->second);
}
LeaveCriticalSection(&m_csTileEntities);
}
level->addAllPendingTileEntities(values);
#if defined(_ENTITIES_RW_SECTION)
EnterCriticalRWSection(&m_csEntities, true);
#else
EnterCriticalSection(&m_csEntities);
{ std::lock_guard<std::mutex> lock(m_csEntities);
#endif
for (int i = 0; i < ENTITY_BLOCKS_LENGTH; i++) {
level->addEntities(entityBlocks[i]);
@ -1436,7 +1424,7 @@ void LevelChunk::load() {
#if defined(_ENTITIES_RW_SECTION)
LeaveCriticalRWSection(&m_csEntities, true);
#else
LeaveCriticalSection(&m_csEntities);
}
#endif
} else {
#if defined(_LARGE_WORLDS)
@ -1450,12 +1438,12 @@ void LevelChunk::unload(bool unloadTileEntities) // 4J - added parameter
loaded = false;
if (unloadTileEntities) {
std::vector<std::shared_ptr<TileEntity> > tileEntitiesToRemove;
EnterCriticalSection(&m_csTileEntities);
{ std::lock_guard<std::mutex> lock(m_csTileEntities);
for (auto it = tileEntities.begin(); it != tileEntities.end();
it++) {
tileEntitiesToRemove.push_back(it->second);
}
LeaveCriticalSection(&m_csTileEntities);
}
auto itEnd = tileEntitiesToRemove.end();
for (auto it = tileEntitiesToRemove.begin(); it != itEnd; it++) {
@ -1467,7 +1455,7 @@ void LevelChunk::unload(bool unloadTileEntities) // 4J - added parameter
#if defined(_ENTITIES_RW_SECTION)
EnterCriticalRWSection(&m_csEntities, true);
#else
EnterCriticalSection(&m_csEntities);
{ std::lock_guard<std::mutex> lock(m_csEntities);
#endif
for (int i = 0; i < ENTITY_BLOCKS_LENGTH; i++) {
level->removeEntities(entityBlocks[i]);
@ -1475,7 +1463,7 @@ void LevelChunk::unload(bool unloadTileEntities) // 4J - added parameter
#if defined(_ENTITIES_RW_SECTION)
LeaveCriticalRWSection(&m_csEntities, true);
#else
LeaveCriticalSection(&m_csEntities);
}
#endif
// app.DebugPrintf("Unloaded chunk %d, %d\n", x, z);
@ -1492,7 +1480,7 @@ void LevelChunk::unload(bool unloadTileEntities) // 4J - added parameter
PIXBeginNamedEvent(0, "Saving entities");
ListTag<CompoundTag>* entityTags = new ListTag<CompoundTag>();
EnterCriticalSection(&m_csEntities);
{ std::lock_guard<std::mutex> lock(m_csEntities);
for (int i = 0; i < ENTITY_BLOCKS_LENGTH; i++) {
auto itEnd = entityBlocks[i]->end();
for (std::vector<std::shared_ptr<Entity> >::iterator it =
@ -1508,7 +1496,7 @@ void LevelChunk::unload(bool unloadTileEntities) // 4J - added parameter
// Clear out this list
entityBlocks[i]->clear();
}
LeaveCriticalSection(&m_csEntities);
}
m_unloadedEntitiesTag->put(L"Entities", entityTags);
PIXEndNamedEvent();
@ -1540,7 +1528,7 @@ bool LevelChunk::containsPlayer() {
#if defined(_ENTITIES_RW_SECTION)
EnterCriticalRWSection(&m_csEntities, true);
#else
EnterCriticalSection(&m_csEntities);
{ std::lock_guard<std::mutex> lock(m_csEntities);
#endif
for (int i = 0; i < ENTITY_BLOCKS_LENGTH; i++) {
std::vector<std::shared_ptr<Entity> >* vecEntity = entityBlocks[i];
@ -1549,7 +1537,6 @@ bool LevelChunk::containsPlayer() {
#if defined(_ENTITIES_RW_SECTION)
LeaveCriticalRWSection(&m_csEntities, true);
#else
LeaveCriticalSection(&m_csEntities);
#endif
return true;
}
@ -1558,7 +1545,7 @@ bool LevelChunk::containsPlayer() {
#if defined(_ENTITIES_RW_SECTION)
LeaveCriticalRWSection(&m_csEntities, true);
#else
LeaveCriticalSection(&m_csEntities);
}
#endif
return false;
}
@ -1579,7 +1566,7 @@ void LevelChunk::getEntities(std::shared_ptr<Entity> except, AABB* bb,
// AP - RW critical sections are expensive so enter once in
// Level::getEntities
EnterCriticalSection(&m_csEntities);
{ std::lock_guard<std::mutex> lock(m_csEntities);
for (int yc = yc0; yc <= yc1; yc++) {
std::vector<std::shared_ptr<Entity> >* entities = entityBlocks[yc];
@ -1603,7 +1590,7 @@ void LevelChunk::getEntities(std::shared_ptr<Entity> except, AABB* bb,
}
}
}
LeaveCriticalSection(&m_csEntities);
}
}
void LevelChunk::getEntitiesOfClass(const std::type_info& ec, AABB* bb,
@ -1625,7 +1612,7 @@ void LevelChunk::getEntitiesOfClass(const std::type_info& ec, AABB* bb,
// AP - RW critical sections are expensive so enter once in
// Level::getEntitiesOfClass
EnterCriticalSection(&m_csEntities);
{ std::lock_guard<std::mutex> lock(m_csEntities);
for (int yc = yc0; yc <= yc1; yc++) {
std::vector<std::shared_ptr<Entity> >* entities = entityBlocks[yc];
@ -1665,7 +1652,7 @@ void LevelChunk::getEntitiesOfClass(const std::type_info& ec, AABB* bb,
// baseClass.isAssignableFrom(e.getClass())
}
}
LeaveCriticalSection(&m_csEntities);
}
}
int LevelChunk::countEntities() {
@ -1673,7 +1660,7 @@ int LevelChunk::countEntities() {
#if defined(_ENTITIES_RW_SECTION)
EnterCriticalRWSection(&m_csEntities, false);
#else
EnterCriticalSection(&m_csEntities);
{ std::lock_guard<std::mutex> lock(m_csEntities);
#endif
for (int yc = 0; yc < ENTITY_BLOCKS_LENGTH; yc++) {
entityCount += (int)entityBlocks[yc]->size();
@ -1681,7 +1668,7 @@ int LevelChunk::countEntities() {
#if defined(_ENTITIES_RW_SECTION)
LeaveCriticalRWSection(&m_csEntities, false);
#else
LeaveCriticalSection(&m_csEntities);
}
#endif
return entityCount;
}
@ -2226,12 +2213,12 @@ void LevelChunk::compressBlocks() {
// Note - only the extraction of the pointers needs to be done in the
// critical section, since even if the data is unshared whilst we are
// processing this data is still valid (for the server)
EnterCriticalSection(&m_csSharing);
{ std::lock_guard<std::mutex> lock(m_csSharing);
if (sharingTilesAndData) {
blocksToCompressLower = lowerBlocks;
blocksToCompressUpper = upperBlocks;
}
LeaveCriticalSection(&m_csSharing);
}
} else {
// Not the host, simple case
blocksToCompressLower = lowerBlocks;
@ -2325,12 +2312,12 @@ void LevelChunk::compressData() {
// Note - only the extraction of the pointers needs to be done in the
// critical section, since even if the data is unshared whilst we are
// processing this data is still valid (for the server)
EnterCriticalSection(&m_csSharing);
{ std::lock_guard<std::mutex> lock(m_csSharing);
if (sharingTilesAndData) {
dataToCompressLower = lowerData;
dataToCompressUpper = upperData;
}
LeaveCriticalSection(&m_csSharing);
}
} else {
// Not the host, simple case
dataToCompressLower = lowerData;

View file

@ -1,5 +1,7 @@
#pragma once
#include <mutex>
class DataLayer;
class TileEntity;
class Random;
@ -269,7 +271,7 @@ public:
virtual void attemptCompression();
#if defined(SHARING_ENABLED)
static CRITICAL_SECTION m_csSharing; // 4J added
static std::mutex m_csSharing; // 4J added
#endif
// 4J added
#if defined(_ENTITIES_RW_SECTION)
@ -277,9 +279,9 @@ public:
m_csEntities; // AP - we're using a RW critical so we can do multiple
// reads without contention
#else
static CRITICAL_SECTION m_csEntities;
static std::mutex m_csEntities;
#endif
static CRITICAL_SECTION m_csTileEntities; // 4J added
static std::mutex m_csTileEntities; // 4J added
static void staticCtor();
void checkPostProcess(ChunkSource* source, ChunkSource* parent, int x,
int z);

View file

@ -8,7 +8,7 @@
int CompressedTileStorage::deleteQueueIndex;
XLockFreeStack<unsigned char> CompressedTileStorage::deleteQueue[3];
CRITICAL_SECTION CompressedTileStorage::cs_write;
std::mutex CompressedTileStorage::cs_write;
#if defined(PSVITA_PRECOMPUTED_TABLE)
// AP - this will create a precomputed table to speed up getData
@ -35,7 +35,7 @@ CompressedTileStorage::CompressedTileStorage() {
}
CompressedTileStorage::CompressedTileStorage(CompressedTileStorage* copyFrom) {
EnterCriticalSection(&cs_write);
{ std::lock_guard<std::mutex> lock(cs_write);
allocatedSize = copyFrom->allocatedSize;
if (allocatedSize > 0) {
indicesAndData = (unsigned char*)XPhysicalAlloc(
@ -45,7 +45,7 @@ CompressedTileStorage::CompressedTileStorage(CompressedTileStorage* copyFrom) {
} else {
indicesAndData = nullptr;
}
LeaveCriticalSection(&cs_write);
}
#if defined(PSVITA_PRECOMPUTED_TABLE)
CompressedTileStorage_InitTable();
@ -141,9 +141,8 @@ bool CompressedTileStorage::isRenderChunkEmpty(
}
bool CompressedTileStorage::isSameAs(CompressedTileStorage* other) {
EnterCriticalSection(&cs_write);
std::lock_guard<std::mutex> lock(cs_write);
if (allocatedSize != other->allocatedSize) {
LeaveCriticalSection(&cs_write);
return false;
}
@ -168,7 +167,6 @@ bool CompressedTileStorage::isSameAs(CompressedTileStorage* other) {
d0 |= d2;
d4 |= d6;
if (d0 | d4) {
LeaveCriticalSection(&cs_write);
return false;
}
pOld += 8;
@ -180,12 +178,10 @@ bool CompressedTileStorage::isSameAs(CompressedTileStorage* other) {
unsigned char* pucNew = (unsigned char*)pNew;
for (int i = 0; i < allocatedSize - (quickCount * 64); i++) {
if (*pucOld++ != *pucNew++) {
LeaveCriticalSection(&cs_write);
return false;
}
}
LeaveCriticalSection(&cs_write);
return true;
}
@ -244,7 +240,7 @@ inline void CompressedTileStorage::getBlock(int* block, int x, int y, int z) {
void CompressedTileStorage::setData(byteArray dataIn, unsigned int inOffset) {
unsigned short _blockIndices[512];
EnterCriticalSection(&cs_write);
std::lock_guard<std::mutex> lock(cs_write);
unsigned char* data = dataIn.data + inOffset;
// Is the destination fully uncompressed? If so just write our data in -
@ -259,7 +255,6 @@ void CompressedTileStorage::setData(byteArray dataIn, unsigned int inOffset) {
*dataOut++ = data[getIndex(i, j)];
}
}
LeaveCriticalSection(&cs_write);
return;
}
@ -406,7 +401,6 @@ void CompressedTileStorage::setData(byteArray dataIn, unsigned int inOffset) {
}
indicesAndData = newIndicesAndData;
allocatedSize = memToAlloc;
LeaveCriticalSection(&cs_write);
}
#if defined(PSVITA_PRECOMPUTED_TABLE)
@ -598,7 +592,7 @@ int CompressedTileStorage::get(int x, int y, int z) {
// Set an individual tile value
void CompressedTileStorage::set(int x, int y, int z, int val) {
EnterCriticalSection(&cs_write);
std::lock_guard<std::mutex> lock(cs_write);
assert(val != 255);
int block, tile;
getBlockAndTile(&block, &tile, x, y, z);
@ -618,7 +612,6 @@ void CompressedTileStorage::set(int x, int y, int z, int val) {
// continue on to upgrade storage
if (val == ((blockIndices[block] >> INDEX_TILE_SHIFT) &
INDEX_TILE_MASK)) {
LeaveCriticalSection(&cs_write);
return;
}
} else {
@ -627,7 +620,6 @@ void CompressedTileStorage::set(int x, int y, int z, int val) {
data + ((blockIndices[block] >> INDEX_OFFSET_SHIFT) &
INDEX_OFFSET_MASK);
packed[tile] = val;
LeaveCriticalSection(&cs_write);
return;
}
} else {
@ -660,7 +652,6 @@ void CompressedTileStorage::set(int x, int y, int z, int val) {
int bit = (tile & indexmask_bits) * bitspertile;
packed[idx] &= ~(tiletypemask << bit);
packed[idx] |= i << bit;
LeaveCriticalSection(&cs_write);
return;
}
}
@ -669,7 +660,6 @@ void CompressedTileStorage::set(int x, int y, int z, int val) {
compress(block);
}
};
LeaveCriticalSection(&cs_write);
}
// Sets a region of tile values with the data at offset position in the array
@ -743,7 +733,6 @@ int CompressedTileStorage::getDataRegion(byteArray dataInOut, int x0, int y0,
}
void CompressedTileStorage::staticCtor() {
InitializeCriticalSectionAndSpinCount(&cs_write, 5120);
for (int i = 0; i < 3; i++) {
deleteQueue[i].Initialize();
}
@ -793,7 +782,7 @@ void CompressedTileStorage::compress(int upgradeBlock /*=-1*/) {
(upgradeBlock > -1); // If an upgrade block is specified, we'll always
// need to recompress - otherwise default to false
EnterCriticalSection(&cs_write);
std::lock_guard<std::mutex> lock(cs_write);
unsigned short* blockIndices = (unsigned short*)indicesAndData;
unsigned char* data = indicesAndData + 1024;
@ -1131,7 +1120,6 @@ void CompressedTileStorage::compress(int upgradeBlock /*=-1*/) {
indicesAndData = newIndicesAndData;
allocatedSize = memToAlloc;
}
LeaveCriticalSection(&cs_write);
}
int CompressedTileStorage::getAllocatedSize(int* count0, int* count1,

View file

@ -1,4 +1,5 @@
#pragma once
#include <mutex>
#if !defined(__linux__)
#include "../../Platform/x64headers/xmcore.h"
#endif
@ -157,7 +158,7 @@ public:
static unsigned char compressBuffer[32768 + 256];
static CRITICAL_SECTION cs_write;
static std::mutex cs_write;
int getAllocatedSize(int* count0, int* count1, int* count2, int* count4,
int* count8);

View file

@ -1,3 +1,4 @@
#include <mutex>
#include <thread>
#include <chrono>
@ -8,7 +9,7 @@
#include "../LevelData.h"
#include "McRegionChunkStorage.h"
CRITICAL_SECTION McRegionChunkStorage::cs_memory;
std::mutex McRegionChunkStorage::cs_memory;
std::deque<DataOutputStream*> McRegionChunkStorage::s_chunkDataQueue;
int McRegionChunkStorage::s_runningThreadCount = 0;
@ -199,14 +200,15 @@ void McRegionChunkStorage::save(Level* level, LevelChunk* levelChunk) {
PIXEndNamedEvent();
PIXBeginNamedEvent(0, "Updating chunk queue");
EnterCriticalSection(&cs_memory);
{ std::lock_guard<std::mutex> lock(cs_memory);
s_chunkDataQueue.push_back(output);
LeaveCriticalSection(&cs_memory);
}
PIXEndNamedEvent();
} else {
EnterCriticalSection(&cs_memory);
CompoundTag* tag;
{ std::lock_guard<std::mutex> lock(cs_memory);
PIXBeginNamedEvent(0, "Creating tags\n");
CompoundTag* tag = new CompoundTag();
tag = new CompoundTag();
CompoundTag* levelData = new CompoundTag();
tag->put(L"Level", levelData);
OldChunkStorage::save(levelChunk, level, levelData);
@ -214,7 +216,7 @@ void McRegionChunkStorage::save(Level* level, LevelChunk* levelChunk) {
PIXBeginNamedEvent(0, "NbtIo writing\n");
NbtIo::write(tag, output);
PIXEndNamedEvent();
LeaveCriticalSection(&cs_memory);
}
PIXBeginNamedEvent(0, "Output closing\n");
output->close();
PIXEndNamedEvent();
@ -222,12 +224,12 @@ void McRegionChunkStorage::save(Level* level, LevelChunk* levelChunk) {
// 4J Stu - getChunkDataOutputStream makes a new DataOutputStream that
// points to a new ChunkBuffer( ByteArrayOutputStream ) We should clean
// these up when we are done
EnterCriticalSection(&cs_memory);
{ std::lock_guard<std::mutex> lock(cs_memory);
PIXBeginNamedEvent(0, "Cleaning up\n");
output->deleteChildStream();
delete output;
delete tag;
LeaveCriticalSection(&cs_memory);
}
PIXEndNamedEvent();
}
MemSect(0);
@ -321,8 +323,6 @@ void McRegionChunkStorage::flush() {
}
void McRegionChunkStorage::staticCtor() {
InitializeCriticalSectionAndSpinCount(&cs_memory, 5120);
for (unsigned int i = 0; i < 3; ++i) {
char threadName[256];
sprintf(threadName, "McRegion Save thread %d\n", i);
@ -355,14 +355,15 @@ int McRegionChunkStorage::runSaveThreadProc(void* lpParam) {
DataOutputStream* dos = nullptr;
while (running) {
if (TryEnterCriticalSection(&cs_memory)) {
{ std::unique_lock<std::mutex> lock(cs_memory, std::try_to_lock);
if (lock.owns_lock()) {
lastQueueSize = s_chunkDataQueue.size();
if (lastQueueSize > 0) {
dos = s_chunkDataQueue.front();
s_chunkDataQueue.pop_front();
}
s_runningThreadCount++;
LeaveCriticalSection(&cs_memory);
lock.unlock();
if (dos) {
PIXBeginNamedEvent(0, "Saving chunk");
@ -375,9 +376,10 @@ int McRegionChunkStorage::runSaveThreadProc(void* lpParam) {
delete dos;
dos = nullptr;
EnterCriticalSection(&cs_memory);
{ std::lock_guard<std::mutex> lock2(cs_memory);
s_runningThreadCount--;
LeaveCriticalSection(&cs_memory);
}
}
}
// If there was more than one thing in the queue last time we checked,
@ -401,30 +403,32 @@ void McRegionChunkStorage::WaitIfTooManyQueuedChunks() { WaitForSaves(); }
// Static
void McRegionChunkStorage::WaitForAllSaves() {
// Wait for there to be no more tasks to be processed...
EnterCriticalSection(&cs_memory);
size_t queueSize = s_chunkDataQueue.size();
LeaveCriticalSection(&cs_memory);
size_t queueSize;
{ std::lock_guard<std::mutex> lock(cs_memory);
queueSize = s_chunkDataQueue.size();
}
while (queueSize > 0) {
std::this_thread::sleep_for(std::chrono::milliseconds(10));
EnterCriticalSection(&cs_memory);
{ std::lock_guard<std::mutex> lock(cs_memory);
queueSize = s_chunkDataQueue.size();
LeaveCriticalSection(&cs_memory);
}
}
// And then wait for there to be no running threads that are processing
// these tasks
EnterCriticalSection(&cs_memory);
int runningThreadCount = s_runningThreadCount;
LeaveCriticalSection(&cs_memory);
int runningThreadCount;
{ std::lock_guard<std::mutex> lock(cs_memory);
runningThreadCount = s_runningThreadCount;
}
while (runningThreadCount > 0) {
std::this_thread::sleep_for(std::chrono::milliseconds(10));
EnterCriticalSection(&cs_memory);
{ std::lock_guard<std::mutex> lock(cs_memory);
runningThreadCount = s_runningThreadCount;
LeaveCriticalSection(&cs_memory);
}
}
}
@ -434,17 +438,18 @@ void McRegionChunkStorage::WaitForSaves() {
static const int DESIRED_QUEUE_SIZE = 6;
// Wait for the queue to reduce to a level where we should add more elements
EnterCriticalSection(&cs_memory);
size_t queueSize = s_chunkDataQueue.size();
LeaveCriticalSection(&cs_memory);
size_t queueSize;
{ std::lock_guard<std::mutex> lock(cs_memory);
queueSize = s_chunkDataQueue.size();
}
if (queueSize > MAX_QUEUE_SIZE) {
while (queueSize > DESIRED_QUEUE_SIZE) {
std::this_thread::sleep_for(std::chrono::milliseconds(10));
EnterCriticalSection(&cs_memory);
{ std::lock_guard<std::mutex> lock(cs_memory);
queueSize = s_chunkDataQueue.size();
LeaveCriticalSection(&cs_memory);
}
}
}
}

View file

@ -1,5 +1,7 @@
#pragma once
#include <mutex>
#include "ChunkStorage.h"
#include "../LevelChunk.h"
#include "RegionFileCache.h"
@ -12,7 +14,7 @@ class McRegionChunkStorage : public ChunkStorage {
private:
const std::wstring m_prefix;
ConsoleSaveFile* m_saveFile;
static CRITICAL_SECTION cs_memory;
static std::mutex cs_memory;
std::unordered_map<int64_t, byteArray> m_entityData;

View file

@ -1,4 +1,5 @@
#include "../../Platform/stdafx.h"
#include <mutex>
#include "../../IO/Files/File.h"
#include "../../IO/Streams/InputOutputStream.h"
#include "../../Headers/net.minecraft.world.entity.h"
@ -196,29 +197,22 @@ bool OldChunkStorage::saveEntities(LevelChunk* lc, Level* level,
lc->lastSaveHadEntities = false;
ListTag<CompoundTag>* entityTags = new ListTag<CompoundTag>();
#if defined(_ENTITIES_RW_SECTION)
EnterCriticalRWSection(&lc->m_csEntities, true);
#else
EnterCriticalSection(&lc->m_csEntities);
#endif
for (int i = 0; i < lc->ENTITY_BLOCKS_LENGTH; i++) {
auto itEnd = lc->entityBlocks[i]->end();
for (std::vector<std::shared_ptr<Entity> >::iterator it =
lc->entityBlocks[i]->begin();
it != itEnd; it++) {
std::shared_ptr<Entity> e = *it;
lc->lastSaveHadEntities = true;
CompoundTag* teTag = new CompoundTag();
if (e->save(teTag)) {
entityTags->add(teTag);
{
std::lock_guard<std::mutex> lock(lc->m_csEntities);
for (int i = 0; i < lc->ENTITY_BLOCKS_LENGTH; i++) {
auto itEnd = lc->entityBlocks[i]->end();
for (std::vector<std::shared_ptr<Entity> >::iterator it =
lc->entityBlocks[i]->begin();
it != itEnd; it++) {
std::shared_ptr<Entity> e = *it;
lc->lastSaveHadEntities = true;
CompoundTag* teTag = new CompoundTag();
if (e->save(teTag)) {
entityTags->add(teTag);
}
}
}
}
#if defined(_ENTITIES_RW_SECTION)
LeaveCriticalRWSection(&lc->m_csEntities, true);
#else
LeaveCriticalSection(&lc->m_csEntities);
#endif
tag->put(L"Entities", entityTags);

View file

@ -1,4 +1,5 @@
#include "../../Platform/stdafx.h"
#include <mutex>
#include "../../IO/Files/File.h"
#include "../../IO/Streams/ByteBuffer.h"
#include "../../Headers/net.minecraft.world.entity.h"
@ -214,28 +215,21 @@ void ZonedChunkStorage::saveEntities(Level* level, LevelChunk* lc) {
std::vector<CompoundTag*> tags;
#ifdef _ENTITIES_RW_SECTION
EnterCriticalRWSection(&lc->m_csEntities, true);
#else
EnterCriticalSection(&lc->m_csEntities);
#endif
for (int i = 0; i < LevelChunk::ENTITY_BLOCKS_LENGTH; i++) {
std::vector<std::shared_ptr<Entity> >* entities = lc->entityBlocks[i];
{
std::lock_guard<std::mutex> lock(lc->m_csEntities);
for (int i = 0; i < LevelChunk::ENTITY_BLOCKS_LENGTH; i++) {
std::vector<std::shared_ptr<Entity> >* entities = lc->entityBlocks[i];
auto itEndTags = entities->end();
for (auto it = entities->begin(); it != itEndTags; it++) {
std::shared_ptr<Entity> e = *it; // entities->at(j);
CompoundTag* cp = new CompoundTag();
cp->putInt(L"_TYPE", 0);
e->save(cp);
tags.push_back(cp);
auto itEndTags = entities->end();
for (auto it = entities->begin(); it != itEndTags; it++) {
std::shared_ptr<Entity> e = *it; // entities->at(j);
CompoundTag* cp = new CompoundTag();
cp->putInt(L"_TYPE", 0);
e->save(cp);
tags.push_back(cp);
}
}
}
#ifdef _ENTITIES_RW_SECTION
LeaveCriticalRWSection(&lc->m_csEntities, true);
#else
LeaveCriticalSection(&lc->m_csEntities);
#endif
for (std::unordered_map<TilePos, std::shared_ptr<TileEntity>,
TilePosKeyHash, TilePosKeyEq>::iterator it =

View file

@ -22,10 +22,6 @@ int Connection::writeSizes[256];
void Connection::_init() {
// printf("Con:0x%x init\n",this);
InitializeCriticalSection(&writeLock);
InitializeCriticalSection(&threadCounterLock);
InitializeCriticalSection(&incoming_cs);
running = true;
quitting = false;
disconnected = false;
@ -54,10 +50,6 @@ Connection::~Connection() {
readThread->WaitForCompletion(INFINITE);
writeThread->WaitForCompletion(INFINITE);
DeleteCriticalSection(&writeLock);
DeleteCriticalSection(&threadCounterLock);
DeleteCriticalSection(&incoming_cs);
delete m_hWakeReadThread;
delete m_hWakeWriteThread;
@ -150,29 +142,31 @@ void Connection::send(std::shared_ptr<Packet> packet) {
MemSect(15);
// 4J Jev, synchronized (&writeLock)
EnterCriticalSection(&writeLock);
{
std::lock_guard<std::mutex> lock(writeLock);
estimatedRemaining += packet->getEstimatedSize() + 1;
if (packet->shouldDelay) {
// 4J We have delayed it enough by putting it in the slow queue, so
// don't delay when we actually send it
packet->shouldDelay = false;
outgoing_slow.push(packet);
} else {
outgoing.push(packet);
estimatedRemaining += packet->getEstimatedSize() + 1;
if (packet->shouldDelay) {
// 4J We have delayed it enough by putting it in the slow queue, so
// don't delay when we actually send it
packet->shouldDelay = false;
outgoing_slow.push(packet);
} else {
outgoing.push(packet);
}
}
// 4J Jev, end synchronized.
LeaveCriticalSection(&writeLock);
MemSect(0);
}
void Connection::queueSend(std::shared_ptr<Packet> packet) {
if (quitting) return;
EnterCriticalSection(&writeLock);
estimatedRemaining += packet->getEstimatedSize() + 1;
outgoing_slow.push(packet);
LeaveCriticalSection(&writeLock);
{
std::lock_guard<std::mutex> lock(writeLock);
estimatedRemaining += packet->getEstimatedSize() + 1;
outgoing_slow.push(packet);
}
}
bool Connection::writeTick() {
@ -189,13 +183,13 @@ bool Connection::writeTick() {
fakeLag)) {
std::shared_ptr<Packet> packet;
EnterCriticalSection(&writeLock);
{
std::lock_guard<std::mutex> lock(writeLock);
packet = outgoing.front();
outgoing.pop();
estimatedRemaining -= packet->getEstimatedSize() + 1;
LeaveCriticalSection(&writeLock);
packet = outgoing.front();
outgoing.pop();
estimatedRemaining -= packet->getEstimatedSize() + 1;
}
Packet::writePacket(packet, bufferedDos);
#if defined(__linux__)
@ -238,13 +232,13 @@ bool Connection::writeTick() {
// synchronized (writeLock) {
EnterCriticalSection(&writeLock);
{
std::lock_guard<std::mutex> lock(writeLock);
packet = outgoing_slow.front();
outgoing_slow.pop();
estimatedRemaining -= packet->getEstimatedSize() + 1;
LeaveCriticalSection(&writeLock);
packet = outgoing_slow.front();
outgoing_slow.pop();
estimatedRemaining -= packet->getEstimatedSize() + 1;
}
// If the shouldDelay flag is still set at this point then we want to
// write it to QNet as a single packet with priority flags Otherwise
@ -329,11 +323,12 @@ bool Connection::readTick() {
if (packet != nullptr) {
readSizes[packet->getId()] += packet->getEstimatedSize() + 1;
EnterCriticalSection(&incoming_cs);
if (!quitting) {
incoming.push(packet);
{
std::lock_guard<std::mutex> lock(incoming_cs);
if (!quitting) {
incoming.push(packet);
}
}
LeaveCriticalSection(&incoming_cs);
didSomething = true;
} else {
// printf("Con:0x%x readTick close EOS\n",this);
@ -420,9 +415,11 @@ void Connection::tick() {
if (estimatedRemaining > 1 * 1024 * 1024) {
close(DisconnectPacket::eDisconnect_Overflow);
}
EnterCriticalSection(&incoming_cs);
bool empty = incoming.empty();
LeaveCriticalSection(&incoming_cs);
bool empty;
{
std::lock_guard<std::mutex> lock(incoming_cs);
empty = incoming.empty();
}
if (empty) {
#if CONNECTION_ENABLE_TIMEOUT_DISCONNECT
if (noInputTicks++ == MAX_TICKS_WITHOUT_INPUT) {
@ -461,16 +458,17 @@ void Connection::tick() {
// changed to use a eAppAction_ExitPlayerPreLogin which will run in the main
// loop, so the connection will not be ticked at that point
EnterCriticalSection(&incoming_cs);
// 4J Stu - If disconnected, then we shouldn't process incoming packets
std::vector<std::shared_ptr<Packet> > packetsToHandle;
while (!disconnected && !g_NetworkManager.IsLeavingGame() &&
g_NetworkManager.IsInSession() && !incoming.empty() && max-- >= 0) {
std::shared_ptr<Packet> packet = incoming.front();
packetsToHandle.push_back(packet);
incoming.pop();
{
std::lock_guard<std::mutex> lock(incoming_cs);
while (!disconnected && !g_NetworkManager.IsLeavingGame() &&
g_NetworkManager.IsInSession() && !incoming.empty() && max-- >= 0) {
std::shared_ptr<Packet> packet = incoming.front();
packetsToHandle.push_back(packet);
incoming.pop();
}
}
LeaveCriticalSection(&incoming_cs);
// MGH - moved the packet handling outside of the incoming_cs block, as it
// was locking up sometimes when disconnecting
@ -492,9 +490,11 @@ void Connection::tick() {
// 4J - split the following condition (used to be disconnect &&
// iscoming.empty()) so we can wrap the access in a critical section
if (disconnected) {
EnterCriticalSection(&incoming_cs);
bool empty = incoming.empty();
LeaveCriticalSection(&incoming_cs);
bool empty;
{
std::lock_guard<std::mutex> lock(incoming_cs);
empty = incoming.empty();
}
if (empty) {
packetListener->onDisconnect(disconnectReason,
disconnectReasonObjects);
@ -540,11 +540,12 @@ int Connection::runRead(void* lpParam) {
Compression::UseDefaultThreadStorage();
CRITICAL_SECTION* cs = &con->threadCounterLock;
std::mutex* cs = &con->threadCounterLock;
EnterCriticalSection(cs);
con->readThreads++;
LeaveCriticalSection(cs);
{
std::lock_guard<std::mutex> lock(*cs);
con->readThreads++;
}
// try {
@ -587,11 +588,12 @@ int Connection::runWrite(void* lpParam) {
Compression::UseDefaultThreadStorage();
CRITICAL_SECTION* cs = &con->threadCounterLock;
std::mutex* cs = &con->threadCounterLock;
EnterCriticalSection(cs);
con->writeThreads++;
LeaveCriticalSection(cs);
{
std::lock_guard<std::mutex> lock(*cs);
con->writeThreads++;
}
// 4J Stu - Adding this to force us to run through the writeTick at least
// once after the event is fired Otherwise there is a race between the
@ -614,9 +616,10 @@ int Connection::runWrite(void* lpParam) {
}
// 4J was in a finally block.
EnterCriticalSection(cs);
con->writeThreads--;
LeaveCriticalSection(cs);
{
std::lock_guard<std::mutex> lock(*cs);
con->writeThreads--;
}
ShutdownManager::HasFinished(ShutdownManager::eConnectionWriteThreads);
return 0;

View file

@ -8,6 +8,8 @@
#include "../Headers/net.minecraft.network.packet.h"
#include "../Util/C4JThread.h"
#include <mutex>
#include "Socket.h"
// 4J JEV, size of the threads (bytes).
@ -54,7 +56,7 @@ private:
std::queue<std::shared_ptr<Packet> >
incoming; // 4J - was using synchronizedList...
CRITICAL_SECTION incoming_cs; // ... now has this critical section
std::mutex incoming_cs; // ... now has this critical section
std::queue<std::shared_ptr<Packet> >
outgoing; // 4J - was using synchronizedList - but don't think it is
// required as usage is wrapped in writeLock critical section
@ -93,8 +95,8 @@ private:
void _init();
// 4J Jev, these might be better of as private
CRITICAL_SECTION threadCounterLock;
CRITICAL_SECTION writeLock;
std::mutex threadCounterLock;
std::mutex writeLock;
public:
// 4J Jev, need to delete the critical section.

View file

@ -14,7 +14,7 @@
// link. 2 sockets can be created, one for either end of this local link, the
// end (0 or 1) is passed as a parameter to the ctor.
CRITICAL_SECTION Socket::s_hostQueueLock[2];
std::mutex Socket::s_hostQueueLock[2];
std::queue<std::uint8_t> Socket::s_hostQueue[2];
Socket::SocketOutputStreamLocal* Socket::s_hostOutStream[2];
Socket::SocketInputStreamLocal* Socket::s_hostInStream[2];
@ -26,7 +26,6 @@ void Socket::EnsureStreamsInitialised() {
// concurrently.
static bool initialized = []() -> bool {
for (int i = 0; i < 2; i++) {
InitializeCriticalSection(&Socket::s_hostQueueLock[i]);
s_hostOutStream[i] = new SocketOutputStreamLocal(i);
s_hostInStream[i] = new SocketInputStreamLocal(i);
}
@ -47,11 +46,13 @@ void Socket::Initialise(ServerConnection* serverConnection) {
if (init) {
// Streams already exist just reset queue state and re-open streams.
for (int i = 0; i < 2; i++) {
if (TryEnterCriticalSection(&s_hostQueueLock[i])) {
// Clear the queue
std::queue<std::uint8_t> empty;
std::swap(s_hostQueue[i], empty);
LeaveCriticalSection(&s_hostQueueLock[i]);
{
std::unique_lock<std::mutex> lock(s_hostQueueLock[i], std::try_to_lock);
if (lock.owns_lock()) {
// Clear the queue
std::queue<std::uint8_t> empty;
std::swap(s_hostQueue[i], empty);
}
}
s_hostOutStream[i]->m_streamOpen = true;
s_hostInStream[i]->m_streamOpen = true;
@ -94,7 +95,6 @@ Socket::Socket(INetworkPlayer* player, bool response /* = false*/,
m_hostLocal = hostLocal;
for (int i = 0; i < 2; i++) {
InitializeCriticalSection(&m_queueLockNetwork[i]);
m_inputStream[i] = nullptr;
m_outputStream[i] = nullptr;
m_endClosed[i] = false;
@ -143,11 +143,12 @@ void Socket::pushDataToQueue(const std::uint8_t* pbData, std::size_t dataSize,
return;
}
EnterCriticalSection(&m_queueLockNetwork[queueIdx]);
for (std::size_t i = 0; i < dataSize; ++i) {
m_queueNetwork[queueIdx].push(*pbData++);
{
std::lock_guard<std::mutex> lock(m_queueLockNetwork[queueIdx]);
for (std::size_t i = 0; i < dataSize; ++i) {
m_queueNetwork[queueIdx].push(*pbData++);
}
}
LeaveCriticalSection(&m_queueLockNetwork[queueIdx]);
}
void Socket::addIncomingSocket(Socket* socket) {
@ -244,14 +245,15 @@ Socket::SocketInputStreamLocal::SocketInputStreamLocal(int queueIdx) {
int Socket::SocketInputStreamLocal::read() {
while (m_streamOpen && ShutdownManager::ShouldRun(
ShutdownManager::eConnectionReadThreads)) {
if (TryEnterCriticalSection(&s_hostQueueLock[m_queueIdx])) {
if (s_hostQueue[m_queueIdx].size()) {
std::uint8_t retval = s_hostQueue[m_queueIdx].front();
s_hostQueue[m_queueIdx].pop();
LeaveCriticalSection(&s_hostQueueLock[m_queueIdx]);
return retval;
{
std::unique_lock<std::mutex> lock(s_hostQueueLock[m_queueIdx], std::try_to_lock);
if (lock.owns_lock()) {
if (s_hostQueue[m_queueIdx].size()) {
std::uint8_t retval = s_hostQueue[m_queueIdx].front();
s_hostQueue[m_queueIdx].pop();
return retval;
}
}
LeaveCriticalSection(&s_hostQueueLock[m_queueIdx]);
}
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
@ -269,16 +271,17 @@ int Socket::SocketInputStreamLocal::read(byteArray b) {
int Socket::SocketInputStreamLocal::read(byteArray b, unsigned int offset,
unsigned int length) {
while (m_streamOpen) {
if (TryEnterCriticalSection(&s_hostQueueLock[m_queueIdx])) {
if (s_hostQueue[m_queueIdx].size() >= length) {
for (unsigned int i = 0; i < length; i++) {
b[i + offset] = s_hostQueue[m_queueIdx].front();
s_hostQueue[m_queueIdx].pop();
{
std::unique_lock<std::mutex> lock(s_hostQueueLock[m_queueIdx], std::try_to_lock);
if (lock.owns_lock()) {
if (s_hostQueue[m_queueIdx].size() >= length) {
for (unsigned int i = 0; i < length; i++) {
b[i + offset] = s_hostQueue[m_queueIdx].front();
s_hostQueue[m_queueIdx].pop();
}
return length;
}
LeaveCriticalSection(&s_hostQueueLock[m_queueIdx]);
return length;
}
LeaveCriticalSection(&s_hostQueueLock[m_queueIdx]);
}
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
@ -287,9 +290,10 @@ int Socket::SocketInputStreamLocal::read(byteArray b, unsigned int offset,
void Socket::SocketInputStreamLocal::close() {
m_streamOpen = false;
EnterCriticalSection(&s_hostQueueLock[m_queueIdx]);
std::queue<std::uint8_t>().swap(s_hostQueue[m_queueIdx]);
LeaveCriticalSection(&s_hostQueueLock[m_queueIdx]);
{
std::lock_guard<std::mutex> lock(s_hostQueueLock[m_queueIdx]);
std::queue<std::uint8_t>().swap(s_hostQueue[m_queueIdx]);
}
}
/////////////////////////////////// Socket for output, on local connection
@ -304,9 +308,10 @@ void Socket::SocketOutputStreamLocal::write(unsigned int b) {
if (m_streamOpen != true) {
return;
}
EnterCriticalSection(&s_hostQueueLock[m_queueIdx]);
s_hostQueue[m_queueIdx].push((std::uint8_t)b);
LeaveCriticalSection(&s_hostQueueLock[m_queueIdx]);
{
std::lock_guard<std::mutex> lock(s_hostQueueLock[m_queueIdx]);
s_hostQueue[m_queueIdx].push((std::uint8_t)b);
}
}
void Socket::SocketOutputStreamLocal::write(byteArray b) {
@ -319,19 +324,21 @@ void Socket::SocketOutputStreamLocal::write(byteArray b, unsigned int offset,
return;
}
MemSect(12);
EnterCriticalSection(&s_hostQueueLock[m_queueIdx]);
for (unsigned int i = 0; i < length; i++) {
s_hostQueue[m_queueIdx].push(b[offset + i]);
{
std::lock_guard<std::mutex> lock(s_hostQueueLock[m_queueIdx]);
for (unsigned int i = 0; i < length; i++) {
s_hostQueue[m_queueIdx].push(b[offset + i]);
}
}
LeaveCriticalSection(&s_hostQueueLock[m_queueIdx]);
MemSect(0);
}
void Socket::SocketOutputStreamLocal::close() {
m_streamOpen = false;
EnterCriticalSection(&s_hostQueueLock[m_queueIdx]);
std::queue<std::uint8_t>().swap(s_hostQueue[m_queueIdx]);
LeaveCriticalSection(&s_hostQueueLock[m_queueIdx]);
{
std::lock_guard<std::mutex> lock(s_hostQueueLock[m_queueIdx]);
std::queue<std::uint8_t>().swap(s_hostQueue[m_queueIdx]);
}
}
/////////////////////////////////// Socket for input, on network connection
@ -348,16 +355,16 @@ Socket::SocketInputStreamNetwork::SocketInputStreamNetwork(Socket* socket,
int Socket::SocketInputStreamNetwork::read() {
while (m_streamOpen && ShutdownManager::ShouldRun(
ShutdownManager::eConnectionReadThreads)) {
if (TryEnterCriticalSection(
&m_socket->m_queueLockNetwork[m_queueIdx])) {
if (m_socket->m_queueNetwork[m_queueIdx].size()) {
std::uint8_t retval =
m_socket->m_queueNetwork[m_queueIdx].front();
m_socket->m_queueNetwork[m_queueIdx].pop();
LeaveCriticalSection(&m_socket->m_queueLockNetwork[m_queueIdx]);
return retval;
{
std::unique_lock<std::mutex> lock(m_socket->m_queueLockNetwork[m_queueIdx], std::try_to_lock);
if (lock.owns_lock()) {
if (m_socket->m_queueNetwork[m_queueIdx].size()) {
std::uint8_t retval =
m_socket->m_queueNetwork[m_queueIdx].front();
m_socket->m_queueNetwork[m_queueIdx].pop();
return retval;
}
}
LeaveCriticalSection(&m_socket->m_queueLockNetwork[m_queueIdx]);
}
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
@ -375,18 +382,18 @@ int Socket::SocketInputStreamNetwork::read(byteArray b) {
int Socket::SocketInputStreamNetwork::read(byteArray b, unsigned int offset,
unsigned int length) {
while (m_streamOpen) {
if (TryEnterCriticalSection(
&m_socket->m_queueLockNetwork[m_queueIdx])) {
if (m_socket->m_queueNetwork[m_queueIdx].size() >= length) {
for (unsigned int i = 0; i < length; i++) {
b[i + offset] =
m_socket->m_queueNetwork[m_queueIdx].front();
m_socket->m_queueNetwork[m_queueIdx].pop();
{
std::unique_lock<std::mutex> lock(m_socket->m_queueLockNetwork[m_queueIdx], std::try_to_lock);
if (lock.owns_lock()) {
if (m_socket->m_queueNetwork[m_queueIdx].size() >= length) {
for (unsigned int i = 0; i < length; i++) {
b[i + offset] =
m_socket->m_queueNetwork[m_queueIdx].front();
m_socket->m_queueNetwork[m_queueIdx].pop();
}
return length;
}
LeaveCriticalSection(&m_socket->m_queueLockNetwork[m_queueIdx]);
return length;
}
LeaveCriticalSection(&m_socket->m_queueLockNetwork[m_queueIdx]);
}
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
@ -441,11 +448,12 @@ void Socket::SocketOutputStreamNetwork::writeWithFlags(byteArray b,
else
queueIdx = SOCKET_CLIENT_END;
EnterCriticalSection(&m_socket->m_queueLockNetwork[queueIdx]);
for (unsigned int i = 0; i < length; i++) {
m_socket->m_queueNetwork[queueIdx].push(b[offset + i]);
{
std::lock_guard<std::mutex> lock(m_socket->m_queueLockNetwork[queueIdx]);
for (unsigned int i = 0; i < length; i++) {
m_socket->m_queueNetwork[queueIdx].push(b[offset + i]);
}
}
LeaveCriticalSection(&m_socket->m_queueLockNetwork[queueIdx]);
} else {
XRNM_SEND_BUFFER buffer;
buffer.pbyData = &b[offset];

View file

@ -5,6 +5,7 @@
#include <xrnm.h>
#include <qnet.h>
#endif
#include <mutex>
#include <queue>
#include "../IO/Streams/InputStream.h"
#include "../IO/Streams/OutputStream.h"
@ -107,14 +108,14 @@ private:
int m_end; // 0 for client side or 1 for host side
// For local connections between the host player and the server
static CRITICAL_SECTION s_hostQueueLock[2];
static std::mutex s_hostQueueLock[2];
static std::queue<std::uint8_t> s_hostQueue[2];
static SocketOutputStreamLocal* s_hostOutStream[2];
static SocketInputStreamLocal* s_hostInStream[2];
// For network connections
std::queue<std::uint8_t> m_queueNetwork[2]; // For input data
CRITICAL_SECTION m_queueLockNetwork[2]; // For input data
std::mutex m_queueLockNetwork[2]; // For input data
SocketInputStreamNetwork* m_inputStream[2];
SocketOutputStreamNetwork* m_outputStream[2];
bool m_endClosed[2];

View file

@ -67,8 +67,6 @@ BiomeCache::BiomeCache(BiomeSource* source) {
lastUpdateTime = 0;
this->source = source;
InitializeCriticalSection(&m_CS);
}
BiomeCache::~BiomeCache() {
@ -78,11 +76,10 @@ BiomeCache::~BiomeCache() {
for (auto it = all.begin(); it != all.end(); ++it) {
delete (*it);
}
DeleteCriticalSection(&m_CS);
}
BiomeCache::Block* BiomeCache::getBlockAt(int x, int z) {
EnterCriticalSection(&m_CS);
std::lock_guard<std::mutex> lock(m_CS);
x >>= ZONE_SIZE_BITS;
z >>= ZONE_SIZE_BITS;
int64_t slot =
@ -99,7 +96,6 @@ BiomeCache::Block* BiomeCache::getBlockAt(int x, int z) {
block = it->second;
}
block->lastUse = app.getAppTime();
LeaveCriticalSection(&m_CS);
return block;
}
@ -116,7 +112,7 @@ float BiomeCache::getDownfall(int x, int z) {
}
void BiomeCache::update() {
EnterCriticalSection(&m_CS);
std::lock_guard<std::mutex> lock(m_CS);
int64_t now = app.getAppTime();
int64_t utime = now - lastUpdateTime;
if (utime > DECAY_TIME / 4 || utime < 0) {
@ -136,7 +132,6 @@ void BiomeCache::update() {
}
}
}
LeaveCriticalSection(&m_CS);
}
BiomeArray BiomeCache::getBiomeBlockAt(int x, int z) {

View file

@ -1,4 +1,5 @@
#pragma once
#include <mutex>
#include "../Minecraft.World/Util/JavaIntHash.h"
class BiomeCache {
@ -48,5 +49,5 @@ public:
byteArray getBiomeIndexBlockAt(int x, int z);
private:
CRITICAL_SECTION m_CS;
std::mutex m_CS;
};