2010/7/8 Brian Hurt <[email protected]> > > > On Wed, Jul 7, 2010 at 5:46 PM, Ryan Waters <[email protected]> wrote: > >> On Wed, Jul 7, 2010 at 4:32 PM, Meikel Brandmeyer <[email protected]> wrote: >> > Hi, >> > >> > Am 07.07.2010 um 23:11 schrieb Ryan Waters: >> > >> >>> (send a init-function) >> >>> (send a f)) >> >> >> >> It's not guaranteed the init-function will complete before f. >> > >> > I doubt that. Since only one action can be active at a time and the >> ordering is preserved, init-function will be complete before f by >> definition: f is not started until init-function is complete. (And btw: no >> other g can happen between init-function and f, because the agent is not yet >> known to the outside world) >> > >> > Sincerely >> > Meikel >> > >> >> My apologies - I read the code wrong and should explain more of what I >> see. When the if is true, the ordering of init-function and f is >> guaranteed so init-function will complete before f. However, on any >> subsequent calls to example, there are no language guarantees that >> keep the if from evaluating to false, calling (send @my-ref f), but >> only after the previous call to (send a init-function). >> >> Stated another way, it's technically possible the agent calls won't >> complete before a subsequent call to example. >> >> > I don't care if the agent calls complete before the next call to example. > I care that the init function is run in the agent before any of the f > functions are called. > > A more specific question is: is the enqueing of messages to agents part of > committing the transaction, or not? The messages aren't enqueued unless the > transaction commits, that much is clear. But consider the following > scenario: Thread #1 comes in and calls example for the first time. So this > fires off a transaction that initializes the reference, and sends two > messages to the agent- initialize and f. Then, the very nanosecond that > thread #1's transaction commits, the operating system decides to swap thread > #1 out to disk, or preempt it, or whatever, and thread #2 comes and calls > example. Now, since the first transaction has completed, thread #2 takes > the else branch, and just sends it's f to the agent. > > Now, if the messages are sent as part of committing the transaction, there > is no problem- the nanosecond the transaction commits, the messages are > already safely enqueued on their way to the agent (even if they haven't been > executed yet), and thread #2's f gets enqueued behind them. But if the > messages are sent after the transaction commits, then there is a problem. > In this case, it's possible that thread #2 can sneak in between the time > that thread #1 commits and thread #1 enqueues it's messages for the agent, > allowing thread #2's f to execute before the initialization function can > execute. The fact that the window of vulnerability for this race condition > may be very small doesn't help at all, I've both seen and had to track down > race conditions where the window of vulnerability was mere nanoseconds- the > words "not fun" come to mind. > > It's sounding like the answer is no, I can't depend upon this. >
Seems to me that your fear is justified: http://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LockingTransaction.java#L358 -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to [email protected] Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/clojure?hl=en
