On 31/07/2015 5:54 AM, Kim Barrett wrote:
On Jul 30, 2015, at 8:09 AM, David Holmes <david.hol...@oracle.com> wrote:
On 30/07/2015 9:57 PM, Peter Levart wrote:
'r' has been enqueued.
Thread-1:
r.isEnqueued() &&
q.poll() == null &&
r.isEnqueued()
Thread-2:
q.poll();
Sequence of actions:
T1: r.isEnqueued() ==> true
T2: q.poll() executed to the following point (see HERE) and 'r' was the
last element in the queue ('head' has been assigned to null):
Yeah thanks - just realized it is that darned unsynchronized "fast-path" again.
What a mess.
It a kind of inverse of the original problem.
Original: don't update reference state to enqueued before the queue is updated
This one: don't update the queue state to empty before the reference state
shows it is de-queued.
So yes the fix here is to move "r.queue = null" to before the assignment to
head.
Bring on the next race ;-)
I agree with everything David said above. Bleh!
So I think I can either:
1. Go ahead with my change + Peter's change.
2. Give this back to core-libs while I step carefully away :-)
I *think* option (1) is at least an improvement. But I completely
missed Peter's race, despite having specifically looked for problems
there, so take my opinion with an appropriate quantity of salt.
I vote for 1 as well. I think we have now given good coverage to the two
sources of problems (the two lock-free regions):
- reference queue state can be seen while queue state is in transition
- queue empty state can be seen while reference state is in transition
Oh for a tool that would do this analysis for us :(
Thanks,
David