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
-~----------~----~----~----~------~----~------~--~---

Attachment: 0001-fixes-commute-after-set.patch
Description: Binary data

Reply via email to