http://bugs.winehq.org/show_bug.cgi?id=14717
--- Comment #277 from Jörg Höhle hoehle@users.sourceforge.net 2012-03-08 04:18:39 CST ---
We increment the buffer's sec_mixpos directly, and "fix" its overflow later. _GetCurrentPosition manages to sneak in before we fix it
Choices:
1. Choose another design. E.g. the lock-less winealsa.drv design sketched in bug #29531, comment #7 solely shares held_frames among threads, where InterlockedExchangeAdd suffices, there's no need for a modulo operation.
2. What about: see = This->sec_mixpos; repeat { old = see; new = (see + added) % size; see = InterlockedCompareExchange(&This->sec_mixpos,new,old); } until (see == old);
You can turn that into an inline InterlockedModuloAdd (except C89 does not say what exactly happens when see+added < 0, unlike C99 IIRC). You want to guarantee that 0 <= new < size, not face new < 0.