[PATCH 10/25] mciseq: Limit concurrency when starting to play.

Alexandre Julliard julliard at winehq.org
Mon Oct 8 13:32:54 CDT 2012

<Joerg-Cyril.Hoehle at t-systems.com> writes:

> Alexandre wrote:
>>>   if (wmm->dwStatus == MCI_MODE_PAUSE) continue;
>>>   if (wmm->dwStatus != MCI_MODE_PLAY)  break; but that's not the same.  
>>> A concurrent thread might change dwStatus to PAUSE right between the 2 
>>> lines.
>>If the code depends on that sort of thing then it's broken.
>>If another thread can change dwStatus you need a critical section
>>or an interlocked function.
> I believe it's not broken:
> 1. All writers of wmm->dwStatus are already within a critical section
>   (except at mciOpen time where there's no threading to consider).
> 2. The player MUST NOT get stuck in a CS while playing.
> 3. But it must read that variable.
> 4. I believe Interlocked* is strictly superfluous when only reading, so
>    I see no value in InterlockedExchange or InterlockedCompareExchange here.
> The player must consider dwStatus conceptually "volatile" (without requiring
> the broken C keyword). Therefore one has to carefully
> think about possible values of (dwStatus == MCI_PLAY || dwStatus == MODE_PAUSE).
> The value could switch from PAUSE to PLAY just when evaluating ||.

This makes no sense, you can't make assumptions about the generated code
from the shape of the if statements. Also there's no such thing as
"conceptually volatile", unless you add explicit memory barriers.

Alexandre Julliard
julliard at winehq.org

More information about the wine-devel mailing list