Skip to content
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

Windows TLS: ManuallyDrop instead of mem::forget #79893

Merged
merged 1 commit into from
Dec 11, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 4 additions & 7 deletions library/std/src/sys/windows/thread_local_key.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::mem;
use crate::mem::ManuallyDrop;
use crate::ptr;
use crate::sync::atomic::AtomicPtr;
use crate::sync::atomic::Ordering::SeqCst;
Expand Down Expand Up @@ -111,16 +111,13 @@ struct Node {
}

unsafe fn register_dtor(key: Key, dtor: Dtor) {
let mut node = Box::new(Node { key, dtor, next: ptr::null_mut() });
let mut node = ManuallyDrop::new(Box::new(Node { key, dtor, next: ptr::null_mut() }));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we never drop this anyway, couldn't we also just Box::into_raw here and then compare_exchangeing the raw pointer directly? I guess that would mean node.next = head needs to be (*node).next = head and is now unsafe, so maybe the ManuallyDrop is better, but I am somewhat unhappy with the &mut **node (the previous &mut *node was not better imo). I know we can rely on the deref ops on boxes, but it still seems wrong to me to not be using Box::into_raw when this is technically what we want.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess that would mean node.next = head needs to be (*node).next = head and is now unsafe

I went with into_raw first and decided to use ManuallyDrop when I realized this.


let mut head = DTORS.load(SeqCst);
loop {
node.next = head;
match DTORS.compare_exchange(head, &mut *node, SeqCst, SeqCst) {
Ok(_) => {
mem::forget(node);
return;
}
match DTORS.compare_exchange(head, &mut **node, SeqCst, SeqCst) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't really related, but shouldn't we use compare_exchange_weak here ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possible; I don't really have a clear idea for what should be used when.
Since it's not related, that should then probably be fixed by someone else in a separate PR. :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fine, I'll do it when this PR is merged.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@a1phyr Did this end up happening?

Ok(_) => return, // nothing to drop, we successfully added the node to the list
Err(cur) => head = cur,
}
}
Expand Down