-
Notifications
You must be signed in to change notification settings - Fork 506
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use pointers instead of &self
in Latch::set
#1011
Conversation
rayon-core/src/latch.rs
Outdated
L: Latch, | ||
{ | ||
#[inline] | ||
fn set(&self) { | ||
L::set(self); | ||
unsafe fn set(this: *const Self) { | ||
L::set(&**this); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This impl makes me uncomfortable. I previously tried to implement this PR and I think I came up with almost exactly the same patch as you have here, but I wasn't sure what to do with this. Of course I couldn't come up with a case where this actually causes an issue, but implementing this for &Latch
seems like an invitation to create the references we're trying to avoid.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a new LatchRef
to replace this -- let me know what you think!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is very cool. I like it.
`Latch::set` can invalidate its own `&self`, because it releases the owning thread to continue execution, which may then invalidate the latch by deallocation, reuse, etc. We've known about this problem when it comes to accessing latch fields too late, but the possibly dangling reference was still a problem, like rust-lang/rust#55005. The result of that was rust-lang/rust#98017, omitting the LLVM attribute `dereferenceable` on references to `!Freeze` types -- those containing `UnsafeCell`. However, miri's Stacked Borrows implementation is finer- grained than that, only relaxing for the cell itself in the `!Freeze` type. For rayon, that solves the dangling reference in atomic calls, but remains a problem for other fields of a `Latch`. This easiest fix for rayon is to use a raw pointer instead of `&self`. We still end up with some temporary references for stuff like atomics, but those should be fine with the rules above.
d66bdc0
to
f880d02
Compare
bors r+ |
Latch::set
can invalidate its own&self
, because it releases theowning thread to continue execution, which may then invalidate the latch
by deallocation, reuse, etc. We've known about this problem when it
comes to accessing latch fields too late, but the possibly dangling
reference was still a problem, like rust-lang/rust#55005.
The result of that was rust-lang/rust#98017, omitting the LLVM attribute
dereferenceable
on references to!Freeze
types -- those containingUnsafeCell
. However, miri's Stacked Borrows implementation is finer-grained than that, only relaxing for the cell itself in the
!Freeze
type. For rayon, that solves the dangling reference in atomic calls, but
remains a problem for other fields of a
Latch
.This easiest fix for rayon is to use a raw pointer instead of
&self
.We still end up with some temporary references for stuff like atomics,
but those should be fine with the rules above.