Fix locks in TextureLoader class#1147
Fix locks in TextureLoader class#1147xezon wants to merge 2 commits intoTheAssemblyArmada:developfrom
Conversation
xezon
commented
Aug 21, 2024
- Potentially fixes w3dview texture crash #1131
| // If we can't start the load of either a dds or tga for the filename in the task set it to missing. | ||
| if (task->Begin_Load()) { | ||
| FastCriticalSectionClass::LockClass lock(g_backgroundCritSec); | ||
| g_backgroundQueue.Push_Front(task); |
There was a problem hiding this comment.
Lock is missing here on write. Could race.
| int time = rts::Get_Time(); | ||
| TextureLoadTaskClass *task; | ||
|
|
||
| while ((task = g_foregroundQueue.Pop_Front()) != nullptr) { |
There was a problem hiding this comment.
Lock exists before already, but scope can be limited. Optimization.
| { | ||
| FastCriticalSectionClass::LockClass lock(g_backgroundCritSec); | ||
|
|
||
| return !g_backgroundQueue.Empty() && !g_foregroundQueue.Empty(); |
There was a problem hiding this comment.
Lock for g_foregroundQueue is missing here on read.
| TextureLoadTaskClass *thumb_task = texture->Get_Thumbnail_Load_Task(); | ||
|
|
||
| if (!TextureLoader::Is_DX8_Thread()) { | ||
| FastCriticalSectionClass::LockClass lock2(g_backgroundCritSec); |
There was a problem hiding this comment.
Originally takes both locks at the same time. This can be risky and introduce ABA deadlock problem. This can be avoided by limiting scope.
Could perhaps deadlock with LoaderThreadClass::Thread_Function
| } | ||
|
|
||
| if (task != nullptr) { | ||
| if (task->Get_Parent() == &g_backgroundQueue) { |
There was a problem hiding this comment.
This does not need locking. g_backgroundQueue address never changes.
| */ | ||
| void TextureLoader::Request_Background_Loading(TextureBaseClass *texture) | ||
| { | ||
| FastCriticalSectionClass::LockClass lock(g_foregroundCritSec); |
There was a problem hiding this comment.
Lock scope can be limited. Optimization.
| */ | ||
| void TextureLoader::Request_Thumbnail(TextureBaseClass *texture) | ||
| { | ||
| FastCriticalSectionClass::LockClass lock(g_foregroundCritSec); |
There was a problem hiding this comment.
Lock scope can be limited. Optimization.
| void LoaderThreadClass::Thread_Function() | ||
| { | ||
| while (m_isRunning) { | ||
| if (!g_backgroundQueue.Empty()) { |
There was a problem hiding this comment.
Lock for g_backgroundQueue is missing here on read.
| if (!g_backgroundQueue.Empty()) { | ||
| bool backgroundQueueEmpty; | ||
| { | ||
| FastCriticalSectionClass::LockClass background_lock(g_backgroundCritSec); |
There was a problem hiding this comment.
Originally takes both locks at the same time. This can be risky and introduce ABA deadlock problem. This can be avoided by limiting scope.
Could perhaps deadlock with TextureLoader::Request_Foreground_Loading.
e18df69 to
8fbff61
Compare