Ah, maybe I should have read the thread on ensure before I posted this! =)

(dosync (ensure r) (alter r f))

works.

On Mon, Mar 15, 2010 at 1:10 PM, Garth Sheldon-Coulson <g...@mit.edu> wrote:

> Apologies in advance if this question has a simple answer that I'm
> overlooking!
>
> Suppose I have a ref or atom and I periodically need to call a long-running
> function on it:
>
> (def r (ref 0))
> (defn f [_] (Thread/sleep 1000) -10)
>
> Suppose also that the ref is being modified from other threads at shorter
> intervals than the execution time of f. I'll simulate this with:
>
> (future (loop [] (Thread/sleep 500) (dosync (alter r inc)) (recur)))
>
> In this situation, the following will never return:
>
> (dosync (alter r f))
>
> The reason is that the value of r never stays the same long enough for f to
> see and then update a consistent value.
>
> Is there a way to cause r to be locked during the (dosync (alter r f)) so
> that all other alterations will be held until after it completes? I know
> this isn't normally the desired behavior, but is it possible to obtain?
>
> Neither of the following works:
> (locking r (dosync (alter r f)))
> (dosync (locking r (alter r f)))
>
> I could simulate part of the behavior I want with agents and await, but
> then I lose the ability to synchronize alterations.
>
> Thanks for any insights!
>
> Garth
>

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

Reply via email to