theolaurent / ocaml-reagent

An implementation of reagents for multicore OCaml
ISC License
4 stars 0 forks source link

Swap is broken #14

Open kayceesrk opened 9 years ago

kayceesrk commented 9 years ago

swap is racy. In all_messages (MSQueue.snapshot e.incoming) >+> Reagent.send push_message [1], channel state can change between checking for pending offers in all_messages and posting a new message.

[1] https://github.com/theolaurent/ocaml-reagent/blob/master/communication/Channel.ml#L49

theolaurent commented 9 years ago

I have a simple workaround. we could have an ensure reagent : 'a casref -> ('a -> bool) -> ('b, 'b) reagent that is basically a noop except that:

While deeply changing the internals might still be a good idea, because it might simplify some things, I think this is an interesting reagent anyway. And it could be use as a fix for the channels.

theolaurent commented 9 years ago

Or why not a "read and freeze" reagent (of type 'a casref -> (unit, 'a) reagent)? That one would read a reference while adding the same CAS that don't change the value to the reaction.

kayceesrk commented 9 years ago

I like it. :+1: It sounds very similar to STM read log behavior. Essentially, you read a transaction variable and commit only if the variable hasn't changed.

The interesting question is what happens when there is non-detectable changes. Support there is a reference r which happens to have a value v. With read and freeze, you'd add a cas r v v to the reaction. Concurrently, if two different reagents concurrently changes r from v --> x and then from x --> v again, should we care about the fact that value changed? Is this change benign?

STMs typically consider this change to be malign; they'd use a version number to track changes to the reference. Thoughts?

theolaurent commented 9 years ago

As the whole kCAS system on which are built the reactions (an thus the reagent) does not take that kind of change into account anyway, I would tend to think we can consider them as benign...