
If you share IORefs between threads and run on a multiprocessor, you are at the mercy of both sequential optimisations and your architecture's memory consistency guarantees. In other words, don't do it. Use communication primitives that have strong properties in a multi-threaded setting. I realised this paragraph is a bit stronger than I meant. Of course it's fine to share IORefs between threads as long as you use a proper communication primitive to synchronise access to the IORef. eg. using one MVar to lock on a bunch of IORefs is perfectly fine (this is how GHC's IO library is implemented).
is every MVar access is a synchronisation point (in terms of memory update propagation between threads, not just in terms of thread interaction)? if that is the case, I don't have much to complain about regarding point 2, as I avoid IORefs even in the sequential case. just as long as any IORef fans are warned about the "interesting" (and usually nonobvious) effects that might accompany them through their debugging sessions if they use CH. the problem here is that synchronisation is used with two meanings: a) blocking/unblocking threads to coordinate access to shared resources b) propagating changes from thread-local memory to that of other threads perhaps the weirdest example in Java-land is something like synchronized (new Object()) { } which, if you only think of (a), should be a no-op, but wasn't in the old memory model, because entry into/exit from the block caused update of thread-local from external/external from thread-local memory (it is a no-op in the new model, it seems?). i thought that MVars differed from IORefs mainly in supporting (a), and so i was worried about sequential optimisations and memory inconsistency affecting my CH code, in spite of using MVars. as for point 1, i already said that i understand if an implementation does not fully support fairness, but i would advise against taking that as a reason for tagging fairness as an unsupportable property of only theoretical interest: like all the nice theoretical properties of sequential Haskell, it is practically relevant (eg, the simple fact that finalizers are not guaranteed to run has made them nearly useless for me in the past). also, while difficult and potentially less efficient to implement, fairness is not impossible to implement. but as you say, the most important starting point is to pin down what properties CH does or does not support in its GHC implementation. cheers, claus