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

Reply via email to