From 33c756b38e94cef68b3f842c1c2f8bad9d4447a2 Mon Sep 17 00:00:00 2001 From: UIS Date: Thu, 10 Dec 2020 15:23:59 +0300 Subject: Fix multithreading Reorder locks in Event.cpp --- src/AssetManager.cpp | 4 +--- src/Event.cpp | 43 +++++++++++++++++++++++-------------------- src/Event.hpp | 2 +- src/RendererWorld.cpp | 2 +- 4 files changed, 26 insertions(+), 25 deletions(-) diff --git a/src/AssetManager.cpp b/src/AssetManager.cpp index e3e0e05..63dc596 100644 --- a/src/AssetManager.cpp +++ b/src/AssetManager.cpp @@ -658,9 +658,7 @@ BlockFaces &AssetManager::GetBlockModelByBlockId(BlockId block) { blockFaces.faceDirectionVector[i] = Vector(roundf(vec.x), roundf(vec.y), roundf(vec.z)); } - blockIdToBlockFaces.insert(std::make_pair(block, blockFaces)); - - return blockIdToBlockFaces.find(block)->second; + return blockIdToBlockFaces.insert(std::make_pair(block, blockFaces)).first->second; } std::string AssetManager::GetAssetNameByBlockId(BlockId block) { diff --git a/src/Event.cpp b/src/Event.cpp index ea09af3..1ca933f 100644 --- a/src/Event.cpp +++ b/src/Event.cpp @@ -17,7 +17,7 @@ EventListener::~EventListener() { void EventListener::HandleEvent() { OPTICK_EVENT(); - if (!NotEmpty()) + if (Empty()) return; std::lock_guard eventsLock (eventsMutex); @@ -31,11 +31,14 @@ void EventListener::HandleEvent() { void EventListener::HandleAllEvents() { OPTICK_EVENT(); - if (!NotEmpty()) - return; + //This mutexes will locked in PollEvents std::lock_guard eventsLock (eventsMutex); - std::lock_guard handlersLock (handlersMutex); + std::lock_guard handlersLock (handlersMutex); + + if (Empty()) + return; + while (!events.empty()) { Event event = events.front(); events.pop(); @@ -45,11 +48,10 @@ void EventListener::HandleAllEvents() { } } -bool EventListener::NotEmpty() { - PollEvents(); +bool EventListener::Empty() { std::lock_guard eventsLock (eventsMutex); - bool ret = !events.empty(); - return ret; + PollEvents(); + return events.empty(); } void EventListener::RegisterHandler(size_t eventId, const EventListener::HandlerType &data) { @@ -59,16 +61,17 @@ void EventListener::RegisterHandler(size_t eventId, const EventListener::Handler void EventListener::PollEvents() { OPTICK_EVENT(); - std::lock_guard rawLock (rawEventsMutex); - if (rawEvents.empty()) - return; - - std::lock_guard eventsLock (eventsMutex); - std::lock_guard handlersLock (handlersMutex); - while (!rawEvents.empty()) { - Event event = rawEvents.front(); - rawEvents.pop(); - if (handlers[event.id]) - events.push(event); - } + std::lock_guard eventsLock (eventsMutex); + std::lock_guard handlersLock (handlersMutex);//To prevent inverse lock order + + std::lock_guard rawLock (rawEventsMutex); + if (rawEvents.empty()) + return; + + while (!rawEvents.empty()) { + Event event = rawEvents.front(); + rawEvents.pop(); + if (handlers[event.id]) + events.push(event); + } } diff --git a/src/Event.hpp b/src/Event.hpp index 4e04a5a..b1594e7 100644 --- a/src/Event.hpp +++ b/src/Event.hpp @@ -79,7 +79,7 @@ public: void HandleAllEvents(); - bool NotEmpty(); + bool Empty(); void RegisterHandler(size_t eventId, const HandlerType &data); diff --git a/src/RendererWorld.cpp b/src/RendererWorld.cpp index b433609..e3ef738 100644 --- a/src/RendererWorld.cpp +++ b/src/RendererWorld.cpp @@ -33,7 +33,7 @@ void RendererWorld::WorkerFunction(size_t workerId) { LoopExecutionTimeController timer(std::chrono::milliseconds(50)); while (isRunning) { - while (tasksListener.NotEmpty() && isRunning) + while (!tasksListener.Empty() && isRunning) tasksListener.HandleEvent(); timer.Update(); } -- cgit v1.2.3