I think I have grasped the theory behind lock-free FIFOs, why they are needed and their implementation. If I’m not mistaken, they are used when you want to send “temporary streams” of events between threads. For example: I rotate a knob on the UI thread, the corresponding widget fills (pushes) the FIFO with values and the audio thread will consume (pops) them when needed. Once finished, the FIFO will be empty.
However I’m not sure how to avoid data races with “persistent objects”, say for example a vector of regions to be played by the audio thread, while on the UI thread the user can add, remove or re-arrange them freely without stopping the playback. Does a FIFO fit this specific scenario? If so, how?