Hi,
What does that not guarantee (that you'd like to have)?
Consider this scenario:
Play: EnterCS-2 do some stuff, start playing state=Playing; LeaveCS-2
Stop: EnterCS-1 do stuff LeaveCS-1 ; because we want to wait for something to finish wait EnterCS-3 state=Stopped LeaveCS-3
Now issue Stop + Play from 2 threads. Play will start playing while the Stop thread is waiting. Then CS-3 will stomp over the state, leading to inconsistent data structures. The player thread is still running while the state variable indicates Stopped.
What can be done? A. Design the system such that waiting can happen inside the CS. winecoreaudio now can do that.
B. Design the system such that it accomodates transition states. This means a much more complex state machine than the API describes. "Can I restart playing if I'm mid-closing? mid-stopping?" "Am I allowed to refuse starting playing when I acknowledged Stop earlier such that the app now believes I've stopped and submits the next song?" It also likely begs for InterlockedCompareExchange and the sort. You then have to be careful about which slots are valid when. It is hard to get correct. (An example of using Interlocked* is in dlls/mci*/mci*.c notification, can you spot the one fault?)
OO programmers (should) know this well: while mid-method, your object state is not consistent; calling another method may call out to other objects which can again call one of your API methods. But the average API methods are not preprared to face the temporary inconsistent state. Erlang avoids this by design.
C. Restart the transaction Add a loop atop CS-1 After exiting CS-1 and waiting, check whether the state is the one you wish to reach. Otherwise restart the loop. (An example is PlaySound in dlls/winmm/playsound.c). All implementations of interlocked lists do something like this: check the final state and restart if not satisfying.
A variation on the above scenario, found in the MCI: the player thread wants to enter Stopped state at the end, after waiting for all resources to be returned. When is it allowed to modify the state variable?
Regards, Jörg Höhle