File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -64,16 +64,17 @@ impl Debt {
6464 #[ inline]
6565 pub ( crate ) fn pay < T : RefCnt > ( & self , ptr : * const T :: Base ) -> bool {
6666 self . 0
67- // If we don't change anything because there's something else, Relaxed is fine.
67+ // On failure, we have observed that the debt has been paid, but we need to establish a
68+ // happens-before relationship with that debt being paid before we do anything that
69+ // relies on the Arc's strong counter being incremented, so we need to Acquire.
70+ // Arc does not sufficiently take care of this, as the memory model permits its Drop's
71+ // `fetch_sub` to observe itself to be last remaining instance before the `fetch_add`s
72+ // from the debt being repaid, and only after that observation does Arc have an Acquire
73+ // fence.
6874 //
6975 // The Release works as kind of Mutex. We make sure nothing from the debt-protected
7076 // sections leaks below this point.
71- //
72- // Note that if it got paid already, it is inside the reference count. We don't
73- // necessarily observe that increment, but whoever destroys the pointer *must* see the
74- // up to date value, with all increments already counted in (the Arc takes care of that
75- // part).
76- . compare_exchange ( ptr as usize , Self :: NONE , Release , Relaxed )
77+ . compare_exchange ( ptr as usize , Self :: NONE , Release , Acquire )
7778 . is_ok ( )
7879 }
7980
You can’t perform that action at this time.
0 commit comments