Possible bug in LoadBitmap code

So, I have been looking through the source code recently trying to understand the Asset system implemented and found this small issue in LoadBitmap code when passing Immediate = false

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
internal void
LoadBitmap(game_assets *Assets, bitmap_id ID, b32 Immediate)
{
    TIMED_FUNCTION();

    asset *Asset = Assets->Assets + ID.Value;
    if(ID.Value)
    {
        if(AtomicCompareExchangeUInt32((uint32 *)&Asset->State, AssetState_Queued, AssetState_Unloaded) ==
           AssetState_Unloaded)
        {
            task_with_memory *Task = 0;

            if(!Immediate)
            {
                Task = BeginTaskWithMemory(Assets->TranState, false);
            }

            if(Immediate || Task)
            {
             
             //... do stuff
                
            }
            else
            {
                Asset->State = AssetState_Unloaded;
            }
        }
        else if(Immediate)
        {
            // TODO(casey): Do we want to have a more coherent story here
            // for what happens when two force-load people hit the load
            // at the same time?
            asset_state volatile *State = (asset_state volatile *)&Asset->State;
            while(*State == AssetState_Queued) {}
        }
    }
}



When AtomicCompareExchangeUInt32 is executed and if Asset->State is indeed equals to AssetState_Unloaded it will change to AssetState_Queued, Aftherwards it will request a Task, but if there are not Tasks available the Work is not going to be added to the queue and thus the bitmap is not going to be loaded. The thing is, the next time the same bitmap_id is pushed, it will try to load it, as it hasnt been loaded yet, but AtomicCompareExchangeUInt32 will fail as the current state of the Asset is going to be AssetState_Queued instead of AssetState_Unloaded making that particular Asset that couldnt find an available Task, to never load


Maybe I am wrong, so please correct me if so.
I'm not sure I follow you on the logic here. In the case you describe, wouldn't

1
if(Immediate || Task)


evaluate to false (because Task is false), which would cause

1
Asset->State = AssetState_Unloaded;


to execute, thus resetting the state? Maybe I am misunderstanding the bug case you are trying to describe...

Thanks,
- Casey
No, I think you are right. I think I had a brain fart of some sort. Sorry for the noise