diff --git a/Minecraft.Client/Level/ServerLevel.cpp b/Minecraft.Client/Level/ServerLevel.cpp index 34b8ccd5c..2686f7a5a 100644 --- a/Minecraft.Client/Level/ServerLevel.cpp +++ b/Minecraft.Client/Level/ServerLevel.cpp @@ -46,7 +46,7 @@ WeighedTreasureArray ServerLevel::RANDOM_BONUS_ITEMS; C4JThread* ServerLevel::m_updateThread = nullptr; C4JThread::EventArray* ServerLevel::m_updateTrigger; -std::mutex ServerLevel::m_updateCS[3]; +std::recursive_mutex ServerLevel::m_updateCS[3]; Level* ServerLevel::m_level[3]; int ServerLevel::m_updateChunkX[3][LEVEL_CHUNKS_TO_UPDATE_MAX]; @@ -184,7 +184,7 @@ ServerLevel::~ServerLevel() { delete mobSpawner; { - std::lock_guard lock(m_csQueueSendTileUpdates); + std::lock_guard lock(m_csQueueSendTileUpdates); for (auto it = m_queuedSendTileUpdates.begin(); it != m_queuedSendTileUpdates.end(); ++it) { Pos* p = *it; @@ -198,9 +198,9 @@ ServerLevel::~ServerLevel() { } // Make sure that the update thread isn't actually doing any updating - { std::lock_guard lock(m_updateCS[0]); } - { std::lock_guard lock(m_updateCS[1]); } - { std::lock_guard lock(m_updateCS[2]); } + { std::lock_guard lock(m_updateCS[0]); } + { std::lock_guard lock(m_updateCS[1]); } + { std::lock_guard lock(m_updateCS[2]); } m_updateTrigger->ClearAll(); } @@ -440,7 +440,7 @@ void ServerLevel::tickTiles() { unsigned int tickCount = 0; { - std::lock_guard lock(m_updateCS[iLev]); + std::lock_guard 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; @@ -594,7 +594,7 @@ void ServerLevel::addToTickNextTick(int x, int y, int z, int tileId, td.setPriorityTilt(priorityTilt); } { - std::lock_guard lock(m_tickNextTickCS); + std::lock_guard lock(m_tickNextTickCS); if (tickNextTickSet.find(td) == tickNextTickSet.end()) { tickNextTickSet.insert(td); tickNextTickList.insert(td); @@ -613,7 +613,7 @@ void ServerLevel::forceAddTileTick(int x, int y, int z, int tileId, td.delay(tickDelay + levelData->getGameTime()); } { - std::lock_guard lock(m_tickNextTickCS); + std::lock_guard lock(m_tickNextTickCS); if (tickNextTickSet.find(td) == tickNextTickSet.end()) { tickNextTickSet.insert(td); tickNextTickList.insert(td); @@ -636,7 +636,7 @@ void ServerLevel::tickEntities() { void ServerLevel::resetEmptyTime() { emptyTime = 0; } bool ServerLevel::tickPendingTicks(bool force) { - std::lock_guard lock(m_tickNextTickCS); + std::lock_guard lock(m_tickNextTickCS); int count = (int)tickNextTickList.size(); int count2 = (int)tickNextTickSet.size(); if (count != tickNextTickSet.size()) { @@ -685,7 +685,7 @@ bool ServerLevel::tickPendingTicks(bool force) { std::vector* ServerLevel::fetchTicksInChunk(LevelChunk* chunk, bool remove) { - std::lock_guard lock(m_tickNextTickCS); + std::lock_guard lock(m_tickNextTickCS); std::vector* results = new std::vector; ChunkPos* pos = chunk->getPos(); @@ -1215,12 +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) { - std::lock_guard lock(m_csQueueSendTileUpdates); + std::lock_guard lock(m_csQueueSendTileUpdates); m_queuedSendTileUpdates.push_back(new Pos(x, y, z)); } void ServerLevel::runQueuedSendTileUpdates() { - std::lock_guard lock(m_csQueueSendTileUpdates); + std::lock_guard lock(m_csQueueSendTileUpdates); for (auto it = m_queuedSendTileUpdates.begin(); it != m_queuedSendTileUpdates.end(); ++it) { Pos* p = *it; @@ -1237,7 +1237,7 @@ bool ServerLevel::addEntity(std::shared_ptr e) { if (e->instanceof(eTYPE_ITEMENTITY)) { // printf("Adding item entity count //%d\n",m_itemEntities.size()); - std::lock_guard lock(m_limiterCS); + std::lock_guard lock(m_limiterCS); if (m_itemEntities.size() >= MAX_ITEM_ENTITIES) { // printf("Adding - doing remove\n"); removeEntityImmediately(m_itemEntities.front()); @@ -1248,7 +1248,7 @@ bool ServerLevel::addEntity(std::shared_ptr e) { else if (e->instanceof(eTYPE_HANGING_ENTITY)) { // printf("Adding item entity count //%d\n",m_itemEntities.size()); - std::lock_guard lock(m_limiterCS); + std::lock_guard lock(m_limiterCS); if (m_hangingEntities.size() >= MAX_HANGING_ENTITIES) { // printf("Adding - doing remove\n"); @@ -1263,7 +1263,7 @@ bool ServerLevel::addEntity(std::shared_ptr e) { else if (e->instanceof(eTYPE_ARROW)) { // printf("Adding arrow entity count //%d\n",m_arrowEntities.size()); - std::lock_guard lock(m_limiterCS); + std::lock_guard lock(m_limiterCS); if (m_arrowEntities.size() >= MAX_ARROW_ENTITIES) { // printf("Adding - doing remove\n"); removeEntityImmediately(m_arrowEntities.front()); @@ -1274,7 +1274,7 @@ bool ServerLevel::addEntity(std::shared_ptr e) { else if (e->instanceof(eTYPE_EXPERIENCEORB)) { // printf("Adding arrow entity count //%d\n",m_arrowEntities.size()); - std::lock_guard lock(m_limiterCS); + std::lock_guard lock(m_limiterCS); if (m_experienceOrbEntities.size() >= MAX_EXPERIENCEORB_ENTITIES) { // printf("Adding - doing remove\n"); removeEntityImmediately(m_experienceOrbEntities.front()); @@ -1291,16 +1291,16 @@ bool ServerLevel::atEntityLimit(std::shared_ptr e) { bool atLimit = false; if (e->instanceof(eTYPE_ITEMENTITY)) { - std::lock_guard lock(m_limiterCS); + std::lock_guard lock(m_limiterCS); atLimit = m_itemEntities.size() >= MAX_ITEM_ENTITIES; } else if (e->instanceof(eTYPE_HANGING_ENTITY)) { - std::lock_guard lock(m_limiterCS); + std::lock_guard lock(m_limiterCS); atLimit = m_hangingEntities.size() >= MAX_HANGING_ENTITIES; } else if (e->instanceof(eTYPE_ARROW)) { - std::lock_guard lock(m_limiterCS); + std::lock_guard lock(m_limiterCS); atLimit = m_arrowEntities.size() >= MAX_ARROW_ENTITIES; } else if (e->instanceof(eTYPE_EXPERIENCEORB)) { - std::lock_guard lock(m_limiterCS); + std::lock_guard lock(m_limiterCS); atLimit = m_experienceOrbEntities.size() >= MAX_EXPERIENCEORB_ENTITIES; } @@ -1310,30 +1310,30 @@ bool ServerLevel::atEntityLimit(std::shared_ptr e) { // Maintain a cound of primed tnt & falling tiles in this level void ServerLevel::entityAddedExtra(std::shared_ptr e) { if (e->instanceof(eTYPE_ITEMENTITY)) { - std::lock_guard lock(m_limiterCS); + std::lock_guard lock(m_limiterCS); m_itemEntities.push_back(e); // printf("entity added: item entity count now //%d\n",m_itemEntities.size()); } else if (e->instanceof(eTYPE_HANGING_ENTITY)) { - std::lock_guard lock(m_limiterCS); + std::lock_guard lock(m_limiterCS); m_hangingEntities.push_back(e); // printf("entity added: item entity count now //%d\n",m_itemEntities.size()); } else if (e->instanceof(eTYPE_ARROW)) { - std::lock_guard lock(m_limiterCS); + std::lock_guard lock(m_limiterCS); m_arrowEntities.push_back(e); // printf("entity added: arrow entity count now //%d\n",m_arrowEntities.size()); } else if (e->instanceof(eTYPE_EXPERIENCEORB)) { - std::lock_guard lock(m_limiterCS); + std::lock_guard lock(m_limiterCS); m_experienceOrbEntities.push_back(e); // printf("entity added: experience orb entity count now //%d\n",m_arrowEntities.size()); } else if (e->instanceof(eTYPE_PRIMEDTNT)) { - std::lock_guard lock(m_limiterCS); + std::lock_guard lock(m_limiterCS); m_primedTntCount++; } else if (e->instanceof(eTYPE_FALLINGTILE)) { - std::lock_guard lock(m_limiterCS); + std::lock_guard lock(m_limiterCS); m_fallingTileCount++; } } @@ -1342,7 +1342,7 @@ void ServerLevel::entityAddedExtra(std::shared_ptr e) { // item entities from our list void ServerLevel::entityRemovedExtra(std::shared_ptr e) { if (e->instanceof(eTYPE_ITEMENTITY)) { - std::lock_guard lock(m_limiterCS); + std::lock_guard lock(m_limiterCS); // printf("entity removed: item entity count //%d\n",m_itemEntities.size()); auto it = find(m_itemEntities.begin(), m_itemEntities.end(), e); @@ -1353,7 +1353,7 @@ void ServerLevel::entityRemovedExtra(std::shared_ptr e) { // printf("entity removed: item entity count now //%d\n",m_itemEntities.size()); } else if (e->instanceof(eTYPE_HANGING_ENTITY)) { - std::lock_guard lock(m_limiterCS); + std::lock_guard lock(m_limiterCS); // printf("entity removed: item entity count //%d\n",m_itemEntities.size()); auto it = find(m_hangingEntities.begin(), m_hangingEntities.end(), e); @@ -1364,7 +1364,7 @@ void ServerLevel::entityRemovedExtra(std::shared_ptr e) { // printf("entity removed: item entity count now //%d\n",m_itemEntities.size()); } else if (e->instanceof(eTYPE_ARROW)) { - std::lock_guard lock(m_limiterCS); + std::lock_guard lock(m_limiterCS); // printf("entity removed: arrow entity count //%d\n",m_arrowEntities.size()); auto it = find(m_arrowEntities.begin(), m_arrowEntities.end(), e); @@ -1375,7 +1375,7 @@ void ServerLevel::entityRemovedExtra(std::shared_ptr e) { // printf("entity removed: arrow entity count now //%d\n",m_arrowEntities.size()); } else if (e->instanceof(eTYPE_EXPERIENCEORB)) { - std::lock_guard lock(m_limiterCS); + std::lock_guard lock(m_limiterCS); // printf("entity removed: experience orb entity count //%d\n",m_arrowEntities.size()); auto it = find(m_experienceOrbEntities.begin(), @@ -1387,22 +1387,22 @@ void ServerLevel::entityRemovedExtra(std::shared_ptr e) { // printf("entity removed: experience orb entity count now //%d\n",m_arrowEntities.size()); } else if (e->instanceof(eTYPE_PRIMEDTNT)) { - std::lock_guard lock(m_limiterCS); + std::lock_guard lock(m_limiterCS); m_primedTntCount--; } else if (e->instanceof(eTYPE_FALLINGTILE)) { - std::lock_guard lock(m_limiterCS); + std::lock_guard lock(m_limiterCS); m_fallingTileCount--; } } bool ServerLevel::newPrimedTntAllowed() { - std::lock_guard lock(m_limiterCS); + std::lock_guard lock(m_limiterCS); bool retval = m_primedTntCount < MAX_PRIMED_TNT; return retval; } bool ServerLevel::newFallingTileAllowed() { - std::lock_guard lock(m_limiterCS); + std::lock_guard lock(m_limiterCS); bool retval = m_fallingTileCount < MAX_FALLING_TILE; return retval; } @@ -1422,7 +1422,7 @@ int ServerLevel::runUpdate(void* lpParam) { int grassTicks = 0; int lavaTicks = 0; for (unsigned int iLev = 0; iLev < 3; ++iLev) { - std::lock_guard lock(m_updateCS[iLev]); + std::lock_guard 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 diff --git a/Minecraft.Client/Level/ServerLevel.h b/Minecraft.Client/Level/ServerLevel.h index 74b5e87dd..852b391a3 100644 --- a/Minecraft.Client/Level/ServerLevel.h +++ b/Minecraft.Client/Level/ServerLevel.h @@ -17,7 +17,7 @@ private: EntityTracker* tracker; PlayerChunkMap* chunkMap; - std::mutex m_tickNextTickCS; // 4J added + std::recursive_mutex m_tickNextTickCS; // 4J added std::set tickNextTickList; // 4J Was TreeSet std::unordered_set m_queuedSendTileUpdates; // 4J added - std::mutex m_csQueueSendTileUpdates; + std::recursive_mutex m_csQueueSendTileUpdates; protected: int saveInterval; @@ -178,7 +178,7 @@ public: int m_primedTntCount; int m_fallingTileCount; - std::mutex m_limiterCS; + std::recursive_mutex m_limiterCS; std::list > m_itemEntities; std::list > m_hangingEntities; std::list > m_arrowEntities; @@ -212,7 +212,7 @@ public: static int m_randValue[3]; static C4JThread::EventArray* m_updateTrigger; - static std::mutex m_updateCS[3]; + static std::recursive_mutex m_updateCS[3]; static C4JThread* m_updateThread; static int runUpdate(void* lpParam); diff --git a/Minecraft.Client/Minecraft.cpp b/Minecraft.Client/Minecraft.cpp index 1ebd7660b..faf44a939 100644 --- a/Minecraft.Client/Minecraft.cpp +++ b/Minecraft.Client/Minecraft.cpp @@ -987,7 +987,7 @@ void Minecraft::run_middle() { } #endif - { std::lock_guard lock(m_setLevelCS); + { std::lock_guard lock(m_setLevelCS); if (running) { if (reloadTextures) { @@ -3669,7 +3669,7 @@ void Minecraft::setLevel(MultiPlayerLevel* level, int message /*=-1*/, std::shared_ptr forceInsertPlayer /*=nullptr*/, bool doForceStatsSave /*=true*/, bool bPrimaryPlayerSignedOut /*=false*/) { - std::lock_guard lock(m_setLevelCS); + std::lock_guard lock(m_setLevelCS); bool playerAdded = false; this->cameraTargetPlayer = nullptr; diff --git a/Minecraft.Client/Minecraft.h b/Minecraft.Client/Minecraft.h index b2fd0c8eb..751fec019 100644 --- a/Minecraft.Client/Minecraft.h +++ b/Minecraft.Client/Minecraft.h @@ -348,7 +348,7 @@ public: // 4J Stu void forceStatsSave(int idx); - std::mutex m_setLevelCS; + std::recursive_mutex m_setLevelCS; private: // A bit field that store whether a particular quadrant is in the full diff --git a/Minecraft.Client/Network/ServerChunkCache.cpp b/Minecraft.Client/Network/ServerChunkCache.cpp index 0b14d68d9..566fea724 100644 --- a/Minecraft.Client/Network/ServerChunkCache.cpp +++ b/Minecraft.Client/Network/ServerChunkCache.cpp @@ -144,7 +144,7 @@ LevelChunk* ServerChunkCache::create( LevelChunk* lastChunk = chunk; if ((chunk == nullptr) || (chunk->x != x) || (chunk->z != z)) { - { std::lock_guard lock(m_csLoadCreate); + { std::lock_guard lock(m_csLoadCreate); chunk = load(x, z); if (chunk == nullptr) { if (source == nullptr) { @@ -169,7 +169,7 @@ LevelChunk* ServerChunkCache::create( #endif { // Successfully updated the cache - std::lock_guard lock(m_csLoadCreate); + std::lock_guard 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 @@ -649,7 +649,7 @@ bool ServerChunkCache::saveAllEntities() { PIXBeginNamedEvent(0, "Save all entities"); PIXBeginNamedEvent(0, "saving to NBT"); - { std::lock_guard lock(m_csLoadCreate); + { std::lock_guard lock(m_csLoadCreate); for (auto it = m_loadedChunkList.begin(); it != m_loadedChunkList.end(); ++it) { storage->saveEntities(level, *it); @@ -666,7 +666,7 @@ bool ServerChunkCache::saveAllEntities() { } bool ServerChunkCache::save(bool force, ProgressListener* progressListener) { - std::lock_guard lock(m_csLoadCreate); + std::lock_guard lock(m_csLoadCreate); int saves = 0; // 4J - added this to support progressListner diff --git a/Minecraft.Client/Network/ServerChunkCache.h b/Minecraft.Client/Network/ServerChunkCache.h index d39049ac6..ee9d30caa 100644 --- a/Minecraft.Client/Network/ServerChunkCache.h +++ b/Minecraft.Client/Network/ServerChunkCache.h @@ -31,7 +31,7 @@ private: #endif // 4J - added for multithreaded support - std::mutex m_csLoadCreate; + std::recursive_mutex m_csLoadCreate; // 4J - size of cache is defined by size of one side - must be even int XZSIZE; int XZOFFSET; diff --git a/Minecraft.Client/Platform/Common/UI/UIComponent_Panorama.cpp b/Minecraft.Client/Platform/Common/UI/UIComponent_Panorama.cpp index e54781483..2e096319d 100644 --- a/Minecraft.Client/Platform/Common/UI/UIComponent_Panorama.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIComponent_Panorama.cpp @@ -44,7 +44,7 @@ void UIComponent_Panorama::tick() { Minecraft* pMinecraft = Minecraft::GetInstance(); { - std::lock_guard lock(pMinecraft->m_setLevelCS); + std::lock_guard 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 diff --git a/Minecraft.Client/Rendering/Chunk.cpp b/Minecraft.Client/Rendering/Chunk.cpp index 9caf9c73d..9b3681b46 100644 --- a/Minecraft.Client/Rendering/Chunk.cpp +++ b/Minecraft.Client/Rendering/Chunk.cpp @@ -151,7 +151,7 @@ void Chunk::setPos(int x, int y, int z) { assigned = true; { - std::lock_guard lock(levelRenderer->m_csDirtyChunks); + std::lock_guard 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); @@ -722,7 +722,7 @@ void Chunk::reset() { bool retireRenderableTileEntities = false; { - std::lock_guard lock(levelRenderer->m_csDirtyChunks); + std::lock_guard lock(levelRenderer->m_csDirtyChunks); oldKey = levelRenderer->getGlobalIndexForChunk(x, y, z, level); unsigned char refCount = levelRenderer->decGlobalChunkRefCount(x, y, z, level); diff --git a/Minecraft.Client/Rendering/EntityRenderers/ProgressRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/ProgressRenderer.cpp index 3851c94a9..795daf8fb 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/ProgressRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/ProgressRenderer.cpp @@ -4,7 +4,7 @@ #include "ProgressRenderer.h" #include "../../../Minecraft.World/Platform/System.h" -std::mutex ProgressRenderer::s_progress; +std::recursive_mutex ProgressRenderer::s_progress; ProgressRenderer::ProgressRenderer(Minecraft* minecraft) { status = -1; @@ -34,7 +34,7 @@ void ProgressRenderer::_progressStart(int title) { } { - std::lock_guard lock(ProgressRenderer::s_progress); + std::lock_guard lock(ProgressRenderer::s_progress); lastPercent = 0; this->title = title; } @@ -48,7 +48,7 @@ void ProgressRenderer::progressStage(int status) { lastTime = 0; { - std::lock_guard lock(ProgressRenderer::s_progress); + std::lock_guard lock(ProgressRenderer::s_progress); m_eType = eProgressStringType_ID; this->status = status; } @@ -60,7 +60,7 @@ void ProgressRenderer::progressStagePercentage(int i) { // 4J Stu - Removing all progressRenderer rendering. This will be replaced // on the xbox { - std::lock_guard lock(ProgressRenderer::s_progress); + std::lock_guard lock(ProgressRenderer::s_progress); lastPercent = i; } } @@ -68,7 +68,7 @@ void ProgressRenderer::progressStagePercentage(int i) { int ProgressRenderer::getCurrentPercent() { int returnValue = 0; { - std::lock_guard lock(ProgressRenderer::s_progress); + std::lock_guard lock(ProgressRenderer::s_progress); returnValue = lastPercent; } return returnValue; @@ -77,7 +77,7 @@ int ProgressRenderer::getCurrentPercent() { int ProgressRenderer::getCurrentTitle() { int returnValue; { - std::lock_guard lock(ProgressRenderer::s_progress); + std::lock_guard lock(ProgressRenderer::s_progress); returnValue = title; } return returnValue; @@ -86,7 +86,7 @@ int ProgressRenderer::getCurrentTitle() { int ProgressRenderer::getCurrentStatus() { int returnValue; { - std::lock_guard lock(ProgressRenderer::s_progress); + std::lock_guard lock(ProgressRenderer::s_progress); returnValue = status; } return returnValue; @@ -95,25 +95,25 @@ int ProgressRenderer::getCurrentStatus() { ProgressRenderer::eProgressStringType ProgressRenderer::getType() { eProgressStringType returnValue; { - std::lock_guard lock(ProgressRenderer::s_progress); + std::lock_guard lock(ProgressRenderer::s_progress); returnValue = m_eType; } return returnValue; } void ProgressRenderer::setType(eProgressStringType eType) { - std::lock_guard lock(ProgressRenderer::s_progress); + std::lock_guard lock(ProgressRenderer::s_progress); m_eType = eType; } void ProgressRenderer::progressStage(std::wstring& wstrText) { - std::lock_guard lock(ProgressRenderer::s_progress); + std::lock_guard lock(ProgressRenderer::s_progress); m_wstrText = wstrText; m_eType = eProgressStringType_String; } std::wstring& ProgressRenderer::getProgressString(void) { - std::lock_guard lock(ProgressRenderer::s_progress); + std::lock_guard lock(ProgressRenderer::s_progress); std::wstring& temp = m_wstrText; return temp; } diff --git a/Minecraft.Client/Rendering/EntityRenderers/ProgressRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/ProgressRenderer.h index 97d35f0ef..5de0a6c95 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/ProgressRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/ProgressRenderer.h @@ -10,7 +10,7 @@ public: // on a save transfer }; - static std::mutex s_progress; + static std::recursive_mutex s_progress; int getCurrentPercent(); int getCurrentTitle(); diff --git a/Minecraft.Client/Rendering/LevelRenderer.cpp b/Minecraft.Client/Rendering/LevelRenderer.cpp index 201b2f174..540c5cb29 100644 --- a/Minecraft.Client/Rendering/LevelRenderer.cpp +++ b/Minecraft.Client/Rendering/LevelRenderer.cpp @@ -648,7 +648,7 @@ std::wstring LevelRenderer::gatherStats2() { } void LevelRenderer::resortChunks(int xc, int yc, int zc) { - std::lock_guard lock(m_csDirtyChunks); + std::lock_guard lock(m_csDirtyChunks); xc -= CHUNK_XZSIZE / 2; yc -= CHUNK_SIZE / 2; zc -= CHUNK_XZSIZE / 2; @@ -1698,7 +1698,7 @@ bool LevelRenderer::updateDirtyChunks() { ClipChunk* nearChunk = nullptr; // Nearest chunk that is dirty int veryNearCount = 0; int minDistSq = 0x7fffffff; // Distances to this chunk - std::unique_lock dirtyChunksLock(m_csDirtyChunks); + std::unique_lock dirtyChunksLock(m_csDirtyChunks); // Set a flag if we should only rebuild existing chunks, not create anything // new diff --git a/Minecraft.Client/Rendering/LevelRenderer.h b/Minecraft.Client/Rendering/LevelRenderer.h index 7e187e998..f237ebe5c 100644 --- a/Minecraft.Client/Rendering/LevelRenderer.h +++ b/Minecraft.Client/Rendering/LevelRenderer.h @@ -216,7 +216,7 @@ private: public: void fullyFlagRenderableTileEntitiesToBeRemoved(); // 4J added - std::mutex m_csDirtyChunks; + std::recursive_mutex m_csDirtyChunks; bool m_nearDirtyChunk; // 4J - Destroyed Tile Management - these things added so we can track tiles diff --git a/Minecraft.World/IO/Files/ConsoleSaveFileOriginal.h b/Minecraft.World/IO/Files/ConsoleSaveFileOriginal.h index 05ac4981b..3109a4e58 100644 --- a/Minecraft.World/IO/Files/ConsoleSaveFileOriginal.h +++ b/Minecraft.World/IO/Files/ConsoleSaveFileOriginal.h @@ -24,7 +24,7 @@ private: #endif void* pvSaveMem; - std::mutex m_lock; + std::recursive_mutex m_lock; void PrepareForWrite(FileEntry* file, unsigned int nNumberOfBytesToWrite); void MoveDataBeyond(FileEntry* file, unsigned int nNumberOfBytesToWrite); diff --git a/Minecraft.World/IO/Files/ConsoleSaveFileSplit.h b/Minecraft.World/IO/Files/ConsoleSaveFileSplit.h index 4bbd0a6f8..dc42f5564 100644 --- a/Minecraft.World/IO/Files/ConsoleSaveFileSplit.h +++ b/Minecraft.World/IO/Files/ConsoleSaveFileSplit.h @@ -80,7 +80,7 @@ private: #endif void* pvSaveMem; - std::mutex m_lock; + std::recursive_mutex m_lock; void PrepareForWrite(FileEntry* file, unsigned int nNumberOfBytesToWrite); void MoveDataBeyond(FileEntry* file, unsigned int nNumberOfBytesToWrite); diff --git a/Minecraft.World/Level/LevelChunk.cpp b/Minecraft.World/Level/LevelChunk.cpp index 7c7235714..751a466fb 100644 --- a/Minecraft.World/Level/LevelChunk.cpp +++ b/Minecraft.World/Level/LevelChunk.cpp @@ -22,16 +22,16 @@ #include #if defined(SHARING_ENABLED) -std::mutex LevelChunk::m_csSharing; +std::recursive_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 -std::mutex LevelChunk::m_csEntities; +std::recursive_mutex LevelChunk::m_csEntities; #endif -std::mutex LevelChunk::m_csTileEntities; +std::recursive_mutex LevelChunk::m_csTileEntities; bool LevelChunk::touchedSky = false; void LevelChunk::staticCtor() { @@ -48,7 +48,7 @@ void LevelChunk::init(Level* level, int x, int z) { #if defined(_ENTITIES_RW_SECTION) EnterCriticalRWSection(&m_csEntities, true); #else - { std::lock_guard lock(m_csEntities); + { std::lock_guard lock(m_csEntities); #endif entityBlocks = new std::vector >*[ENTITY_BLOCKS_LENGTH]; @@ -79,7 +79,7 @@ void LevelChunk::init(Level* level, int x, int z) { #if defined(_ENTITIES_RW_SECTION) EnterCriticalRWSection(&m_csEntities, true); #else - { std::lock_guard lock(m_csEntities); + { std::lock_guard lock(m_csEntities); #endif for (int i = 0; i < ENTITY_BLOCKS_LENGTH; i++) { entityBlocks[i] = new std::vector >(); @@ -249,7 +249,7 @@ void LevelChunk::setUnsaved(bool unsaved) { void LevelChunk::stopSharingTilesAndData() { #if defined(SHARING_ENABLED) - { std::lock_guard lock(m_csSharing); + { std::lock_guard lock(m_csSharing); lastUnsharedTime = System::currentTimeMillis(); if (!sharingTilesAndData) { return; @@ -315,7 +315,7 @@ void LevelChunk::stopSharingTilesAndData() { // not sharing void LevelChunk::reSyncLighting() { #if defined(SHARING_ENABLED) - { std::lock_guard lock(m_csSharing); + { std::lock_guard lock(m_csSharing); if (isEmpty()) { return; @@ -352,7 +352,7 @@ void LevelChunk::reSyncLighting() { void LevelChunk::startSharingTilesAndData(int forceMs) { #if defined(SHARING_ENABLED) - { std::lock_guard lock(m_csSharing); + { std::lock_guard lock(m_csSharing); if (sharingTilesAndData) { return; } @@ -1178,7 +1178,7 @@ void LevelChunk::addEntity(std::shared_ptr e) { #if defined(_ENTITIES_RW_SECTION) EnterCriticalRWSection(&m_csEntities, true); #else - { std::lock_guard lock(m_csEntities); + { std::lock_guard lock(m_csEntities); #endif entityBlocks[yc]->push_back(e); #if defined(_ENTITIES_RW_SECTION) @@ -1199,7 +1199,7 @@ void LevelChunk::removeEntity(std::shared_ptr e, int yc) { #if defined(_ENTITIES_RW_SECTION) EnterCriticalRWSection(&m_csEntities, true); #else - { std::lock_guard lock(m_csEntities); + { std::lock_guard lock(m_csEntities); #endif // 4J - was entityBlocks[yc]->remove(e); @@ -1242,7 +1242,7 @@ std::shared_ptr LevelChunk::getTileEntity(int x, int y, int z) { // insert when we don't want one) // shared_ptr tileEntity = tileEntities[pos]; std::shared_ptr tileEntity = nullptr; - { std::unique_lock lock(m_csTileEntities); + { std::unique_lock lock(m_csTileEntities); auto it = tileEntities.find(pos); if (it == tileEntities.end()) { @@ -1273,7 +1273,7 @@ std::shared_ptr 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 - { std::lock_guard lock2(m_csTileEntities); + { std::lock_guard lock2(m_csTileEntities); auto newIt = tileEntities.find(pos); if (newIt != tileEntities.end()) { tileEntity = newIt->second; @@ -1284,7 +1284,7 @@ std::shared_ptr LevelChunk::getTileEntity(int x, int y, int z) { } } if (tileEntity != nullptr && tileEntity->isRemoved()) { - { std::lock_guard lock(m_csTileEntities); + { std::lock_guard lock(m_csTileEntities); tileEntities.erase(pos); } return nullptr; @@ -1330,7 +1330,7 @@ void LevelChunk::setTileEntity(int x, int y, int z, tileEntity->clearRemoved(); - { std::lock_guard lock(m_csTileEntities); + { std::lock_guard lock(m_csTileEntities); tileEntities[pos] = tileEntity; } } @@ -1344,7 +1344,7 @@ void LevelChunk::removeTileEntity(int x, int y, int z) { // if (removeThis != null) { // removeThis.setRemoved(); // } - { std::lock_guard lock(m_csTileEntities); + { std::lock_guard lock(m_csTileEntities); auto it = tileEntities.find(pos); if (it != tileEntities.end()) { std::shared_ptr te = tileEntities[pos]; @@ -1402,7 +1402,7 @@ void LevelChunk::load() { #endif std::vector > values; - { std::lock_guard lock(m_csTileEntities); + { std::lock_guard lock(m_csTileEntities); for (auto it = tileEntities.begin(); it != tileEntities.end(); it++) { values.push_back(it->second); } @@ -1412,7 +1412,7 @@ void LevelChunk::load() { #if defined(_ENTITIES_RW_SECTION) EnterCriticalRWSection(&m_csEntities, true); #else - { std::lock_guard lock(m_csEntities); + { std::lock_guard lock(m_csEntities); #endif for (int i = 0; i < ENTITY_BLOCKS_LENGTH; i++) { level->addEntities(entityBlocks[i]); @@ -1434,7 +1434,7 @@ void LevelChunk::unload(bool unloadTileEntities) // 4J - added parameter loaded = false; if (unloadTileEntities) { std::vector > tileEntitiesToRemove; - { std::lock_guard lock(m_csTileEntities); + { std::lock_guard lock(m_csTileEntities); for (auto it = tileEntities.begin(); it != tileEntities.end(); it++) { tileEntitiesToRemove.push_back(it->second); } @@ -1450,7 +1450,7 @@ void LevelChunk::unload(bool unloadTileEntities) // 4J - added parameter #if defined(_ENTITIES_RW_SECTION) EnterCriticalRWSection(&m_csEntities, true); #else - { std::lock_guard lock(m_csEntities); + { std::lock_guard lock(m_csEntities); #endif for (int i = 0; i < ENTITY_BLOCKS_LENGTH; i++) { level->removeEntities(entityBlocks[i]); @@ -1475,7 +1475,7 @@ void LevelChunk::unload(bool unloadTileEntities) // 4J - added parameter PIXBeginNamedEvent(0, "Saving entities"); ListTag* entityTags = new ListTag(); - { std::lock_guard lock(m_csEntities); + { std::lock_guard lock(m_csEntities); for (int i = 0; i < ENTITY_BLOCKS_LENGTH; i++) { auto itEnd = entityBlocks[i]->end(); for (std::vector >::iterator it = @@ -1523,7 +1523,7 @@ bool LevelChunk::containsPlayer() { #if defined(_ENTITIES_RW_SECTION) EnterCriticalRWSection(&m_csEntities, true); #else - { std::lock_guard lock(m_csEntities); + { std::lock_guard lock(m_csEntities); #endif for (int i = 0; i < ENTITY_BLOCKS_LENGTH; i++) { std::vector >* vecEntity = entityBlocks[i]; @@ -1561,7 +1561,7 @@ void LevelChunk::getEntities(std::shared_ptr except, AABB* bb, // AP - RW critical sections are expensive so enter once in // Level::getEntities - { std::lock_guard lock(m_csEntities); + { std::lock_guard lock(m_csEntities); for (int yc = yc0; yc <= yc1; yc++) { std::vector >* entities = entityBlocks[yc]; @@ -1607,7 +1607,7 @@ void LevelChunk::getEntitiesOfClass(const std::type_info& ec, AABB* bb, // AP - RW critical sections are expensive so enter once in // Level::getEntitiesOfClass - { std::lock_guard lock(m_csEntities); + { std::lock_guard lock(m_csEntities); for (int yc = yc0; yc <= yc1; yc++) { std::vector >* entities = entityBlocks[yc]; @@ -1655,7 +1655,7 @@ int LevelChunk::countEntities() { #if defined(_ENTITIES_RW_SECTION) EnterCriticalRWSection(&m_csEntities, false); #else - { std::lock_guard lock(m_csEntities); + { std::lock_guard lock(m_csEntities); #endif for (int yc = 0; yc < ENTITY_BLOCKS_LENGTH; yc++) { entityCount += (int)entityBlocks[yc]->size(); @@ -2208,7 +2208,7 @@ 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) - { std::lock_guard lock(m_csSharing); + { std::lock_guard lock(m_csSharing); if (sharingTilesAndData) { blocksToCompressLower = lowerBlocks; blocksToCompressUpper = upperBlocks; @@ -2307,7 +2307,7 @@ 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) - { std::lock_guard lock(m_csSharing); + { std::lock_guard lock(m_csSharing); if (sharingTilesAndData) { dataToCompressLower = lowerData; dataToCompressUpper = upperData; diff --git a/Minecraft.World/Level/LevelChunk.h b/Minecraft.World/Level/LevelChunk.h index 56356c3e8..0dd5df669 100644 --- a/Minecraft.World/Level/LevelChunk.h +++ b/Minecraft.World/Level/LevelChunk.h @@ -270,7 +270,7 @@ public: virtual void attemptCompression(); #if defined(SHARING_ENABLED) - static std::mutex m_csSharing; // 4J added + static std::recursive_mutex m_csSharing; // 4J added #endif // 4J added #if defined(_ENTITIES_RW_SECTION) @@ -278,9 +278,9 @@ public: m_csEntities; // AP - we're using a RW critical so we can do multiple // reads without contention #else - static std::mutex m_csEntities; + static std::recursive_mutex m_csEntities; #endif - static std::mutex m_csTileEntities; // 4J added + static std::recursive_mutex m_csTileEntities; // 4J added static void staticCtor(); void checkPostProcess(ChunkSource* source, ChunkSource* parent, int x, int z); diff --git a/Minecraft.World/Level/Storage/CompressedTileStorage.cpp b/Minecraft.World/Level/Storage/CompressedTileStorage.cpp index 2c668933c..46c1da9eb 100644 --- a/Minecraft.World/Level/Storage/CompressedTileStorage.cpp +++ b/Minecraft.World/Level/Storage/CompressedTileStorage.cpp @@ -6,7 +6,7 @@ int CompressedTileStorage::deleteQueueIndex; XLockFreeStack CompressedTileStorage::deleteQueue[3]; -std::mutex CompressedTileStorage::cs_write; +std::recursive_mutex CompressedTileStorage::cs_write; #if defined(PSVITA_PRECOMPUTED_TABLE) // AP - this will create a precomputed table to speed up getData @@ -33,7 +33,7 @@ CompressedTileStorage::CompressedTileStorage() { } CompressedTileStorage::CompressedTileStorage(CompressedTileStorage* copyFrom) { - { std::lock_guard lock(cs_write); + { std::lock_guard lock(cs_write); allocatedSize = copyFrom->allocatedSize; if (allocatedSize > 0) { indicesAndData = (unsigned char*)XPhysicalAlloc( @@ -139,7 +139,7 @@ bool CompressedTileStorage::isRenderChunkEmpty( } bool CompressedTileStorage::isSameAs(CompressedTileStorage* other) { - std::lock_guard lock(cs_write); + std::lock_guard lock(cs_write); if (allocatedSize != other->allocatedSize) { return false; } @@ -238,7 +238,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]; - std::lock_guard lock(cs_write); + std::lock_guard lock(cs_write); unsigned char* data = dataIn.data + inOffset; // Is the destination fully uncompressed? If so just write our data in - @@ -590,7 +590,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) { - std::lock_guard lock(cs_write); + std::lock_guard lock(cs_write); assert(val != 255); int block, tile; getBlockAndTile(&block, &tile, x, y, z); @@ -778,7 +778,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 - std::lock_guard lock(cs_write); + std::lock_guard lock(cs_write); unsigned short* blockIndices = (unsigned short*)indicesAndData; unsigned char* data = indicesAndData + 1024; diff --git a/Minecraft.World/Level/Storage/CompressedTileStorage.h b/Minecraft.World/Level/Storage/CompressedTileStorage.h index 5ff5b5b13..42e91e455 100644 --- a/Minecraft.World/Level/Storage/CompressedTileStorage.h +++ b/Minecraft.World/Level/Storage/CompressedTileStorage.h @@ -158,7 +158,7 @@ public: static unsigned char compressBuffer[32768 + 256]; - static std::mutex cs_write; + static std::recursive_mutex cs_write; int getAllocatedSize(int* count0, int* count1, int* count2, int* count4, int* count8); diff --git a/Minecraft.World/Level/Storage/OldChunkStorage.cpp b/Minecraft.World/Level/Storage/OldChunkStorage.cpp index 911d5e670..70ace0f3a 100644 --- a/Minecraft.World/Level/Storage/OldChunkStorage.cpp +++ b/Minecraft.World/Level/Storage/OldChunkStorage.cpp @@ -198,7 +198,7 @@ bool OldChunkStorage::saveEntities(LevelChunk* lc, Level* level, ListTag* entityTags = new ListTag(); { - std::lock_guard lock(lc->m_csEntities); + std::lock_guard lock(lc->m_csEntities); for (int i = 0; i < lc->ENTITY_BLOCKS_LENGTH; i++) { auto itEnd = lc->entityBlocks[i]->end(); for (std::vector >::iterator it =