Also sprach Purl Gurl:
Consider this,
Resource one writes data while semaphore locking.
Resource two needs to write new data and is waiting.
Resource three needs to write new data and is waiting.
Resource two times out.
Resource one finishes.
Resource three writes new data.
Your resource two data has vanished.
Yes, so it has. But that's not a race condition. In the context of this
thread, a race condition is a state in which two parties think that they
have exclusive access to a resource although they might in fact be
sharing it. Two processes writing to the same file would be such a
condition, eventually leading to an inconsistent state of this file.
In your scenario however, data of one source is simply missing. The
difference between that and the above is crucial: With a race condition,
you have the data of several sources indistinguishably mangled into each
other, such as one process partly overwriting data of the other process.
Another thing worthy mentioning is that a race condition, once
happening, cannot be caught. Every involved party honestly believes
things are going right. The case you describe however is trappable.
Process two could for instance create a log file in which it clearly
states that it wasn't able to proceed because it timed out.
The only thing I can grant you is that avoiding races in a portable way
is tricky. The conclusion you drew from that (namely to use a method
that predictibly wont work on any platform) is of course wrong. Every
platform offers at least one way to prevent races and ensure integrity
of data. A portable program therefore choses the method suitable for the
platform it is running on. On UNIXish systems one might be preferring
flock() because it is a convenient and simple mechanism. On windows one
might be using separate lock files or maybe semaphores. If one approach
turns out to have major shortcomings, like producing stale locks, one
would have to work around those as well, often making a significant
rearrangement in the program necessary.
Tassilo