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

Wrap R_MAIN in an UnsafeCell #664

Merged
merged 1 commit into from
Jan 10, 2025
Merged

Wrap R_MAIN in an UnsafeCell #664

merged 1 commit into from
Jan 10, 2025

Conversation

lionel-
Copy link
Contributor

@lionel- lionel- commented Jan 10, 2025

Progress towards #661.
Workaround for #663 (see this issue for context).
Supersedes and closes #662.

  • Make R_MAIN a thread-local variable as this is a nicer way of controlling accesses from other threads.

  • Wrap it in an UnsafeCell so we're able to create multiple &mut to it without compilation warning. This bypasses the borrow checker and causes undefined behaviour. No changes from the status quo in this regard. Alternatively we could pass raw pointers around but that would require lots of unsafe markers everywhere to call methods or set state. So accepting the UB is the easiest way to fix the warning until we can do better.

Progress towards #661
Workaround for #663
@lionel- lionel- requested a review from DavisVaughan January 10, 2025 11:06
Comment on lines +150 to 152
/// We use the `once_cell` crate for init synchronisation because the stdlib
/// equivalent `std::sync::Once` does not have a `wait()` method.
static R_INIT: once_cell::sync::OnceCell<()> = once_cell::sync::OnceCell::new();
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like wait() is a nightly method that may get stabilized soon ish https://doc.rust-lang.org/std/sync/struct.OnceLock.html#method.wait

Comment on lines +608 to +610
// We extend the lifetime to `'static` as `R_MAIN` is effectively static once initialized.
// This allows us to return a `&mut` from the unsafe cell to the caller.
unsafe { std::mem::transmute::<&mut RMain, &'static mut RMain>(main_ref) }
Copy link
Contributor

Choose a reason for hiding this comment

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

The alternative is to remove get_mut() in favor of the with_mut() everywhere right?

Since effectively what we are bypassing here is "the reference may outlive the object" kind of compiler errors?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Correct. I went for minimal changes here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Also I don't think this transmute is problematic since R_MAIN is effectively 'static after init.

@lionel- lionel- merged commit 0f5bc87 into main Jan 10, 2025
6 checks passed
@lionel- lionel- deleted the task/rmain-access branch January 10, 2025 15:42
@github-actions github-actions bot locked and limited conversation to collaborators Jan 10, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants