I think Mark's code exhibits a bug: (def my-ref (ref 1))
(dosync (ref-set my-ref 5) (commute my-ref inc)) ; returns 6 (println "my-ref =" @my-ref) ; prints 7 since my-ref is ref-set, my-ref is in LockingTransaction/sets but its current value in LockingTransaction/vals is set by commute to 6. At the commit point, the commute function is rerun with the latest in-transaction value (6) and then 7 is committed... See the attached patch for a potential fix. Christophe On Mon, Aug 3, 2009 at 12:45 AM, Rich Hickey <richhic...@gmail.com> wrote: > > On Sun, Aug 2, 2009 at 3:20 PM, Mark Volkmann<r.mark.volkm...@gmail.com> > wrote: > > > > The doc for commute says "At the commit point of the transaction, sets > > the value of ref to be: > > (apply fun most-recently-committed-value-of-ref args)". > > > > Looking at the source code in LockingTransaction.java, that doesn't > > seem to always be the case. I see this: > > f.fn.applyTo(RT.cons(vals.get(ref), f.args)) > > > > vals is a HashMap of in-transaction values, not most recently committed > values. > > > > Inside a transaction, Refs get in-transaction values if you do a > > ref-set or alter on them. > > Within a transaction you can ref-set or alter a Ref and then do a > > commute on the same Ref. > > You can't reverse the order. Once you do a commute on a Ref, you can't > > do a ref-set or alter on it in the same transaction. > > > > During transaction commit and immediately before the commute functions > > for the Ref are called, it determines whether the Ref has an > > in-transaction value, meaning that ref-set or alter was called on it. > > If it does not then the most recently committed value for the Ref is > > used for the in-transaction value. > > > > So I think it is only partially true to say that when commute > > functions are rerun during a commit, they use the most recently > > committed values of Refs. That only happens if ref-set and alter were > > not used on the Ref before the call to commute. > > > > Am I understanding this correctly? > > > > Not really. If this transaction is succeeding, and it has written to a > ref prior to its commute, then those writes *are* the most recently > committed value, committed now as a prior part of the same > transaction. > > Rich > > > > -- Professional: http://cgrand.net/ (fr) On Clojure: http://clj-me.blogspot.com/ (en) --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~----------~----~----~----~------~----~------~--~---
0001-fixes-commute-after-set.patch
Description: Binary data