-
-
Notifications
You must be signed in to change notification settings - Fork 14.2k
task: remove wrong comments about non-existent LocalWake trait #52316
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
Conversation
src/libcore/task/wake.rs
Outdated
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 also removed these comments, since there is no LocalWake trait.
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.
Good catch! Sorry, this got left in after I rewrote this code to work differently. I agree that this comment should go away, and it should instead suggest using the local_waker_from_nonlocal or local_waker functions in std::task.
|
@seanmonstar Thanks for pointing out this potential source of confusion! I think this is a documentation issue-- perhaps you can help me figure out the best way to document the required usage. |
|
With |
That's correct!
struct MyOptimizedTaskQueue {
local_queue: RefCell<VecDeque<Arc<MyTask>>>,
sync_queue: crossbeam::sync::SegQueue<Arc<MyTask>>,
}
unsafe impl Send for MyOptimizedTaskQueue {}
unsafe impl Sync for MyOptimizedTaskQueue {}
struct MyTask {
task: RefCell<TaskObj>,
queue: Arc<MyOptimizedTaskQueue>,
}
unsafe impl Send for MyTask {}
unsafe impl Sync for MyTask {}
impl Wake for MyOptimizedTaskQueue {
fn wake(arc_self: &Arc<Self>) {
arc_self.queue.sync_queue.push(arc_self.clone());
}
// HERE is the key bit that `LocalWaker` allows-- because we know we're on the same thread
// from which the `LocalWaker` was created, we know that we can use the `local_queue` `RefCell`
// without any synchronization.
unsafe fn wake_local(arc_self: &Arc<Self>) {
arc_self.queue.local_queue.push(arc_self.clone());
}
}This gives you a single-threaded task system that only requires synchronization for |
|
O_O Being able to be certain that the waker is actually local seems very tricky; I'd be suspicious of code that thinks it's been done safely. Anyways, seems the only thing then here is that the documentation mentions non-existent |
c9086d5 to
4f4e91a
Compare
Right-- you have to create it in one place, on one thread, and then it can be passed down into |
|
@bors r+ rollup |
|
📌 Commit 4f4e91a has been approved by |
task: remove wrong comments about non-existent LocalWake trait ~~A `LocalWaker` is specifically `!Send `, and the unsafety comment around `LocalWaker::new` only specifies that it be safe to call `wake_local`. One could then accidentally promote a `LocalWaker` into a `Waker`, which is universally `Send`, simply via `Waker::from(local_waker)`. A `LocalWaker` the was built expecting to not be `Send`, such as using `Rc`, could be sent to other threads safely.~~ ~~Separately, though somewhat related, `Context` holds a `&LocalWaker` internally, and exposes a `waker() -> &Waker` method. This simply transmutes the `&LocalWaker` to `&Waker`, which would be unsound, except that you can't "send" a `&Waker`, you'd need to clone it first. Since `UnsafeWake::clone_raw` requires that it return a `Waker`, the transmute is not unsound. The transmuted `LocalWaker` will be promoted to a `Waker` correctly.~~ ~~That would mean that if `UnsafeWake::clone_raw` were to be changed, such as returning `Self` instead of `Waker`, this would no longer be sound. Thus, this also adds a comment to `clone_raw` to remember this.~~ r? @cramertj
Rollup of 16 pull requests Successful merges: - #51962 (Provide llvm-strip in llvm-tools component) - #52003 (Implement `Option::replace` in the core library) - #52156 (Update std::ascii::ASCIIExt deprecation notes) - #52242 (NLL: Suggest `ref mut` and `&mut self`) - #52244 (Don't display default generic parameters in diagnostics that compare types) - #52290 (Deny bare trait objects in src/librustc_save_analysis) - #52293 (Deny bare trait objects in librustc_typeck) - #52299 (Deny bare trait objects in src/libserialize) - #52300 (Deny bare trait objects in librustc_target and libtest) - #52302 (Deny bare trait objects in the rest of rust) - #52310 (Backport 1.27.1 release notes to master) - #52314 (Fix ICE when using a pointer cast as array size) - #52315 (Resolve FIXME(#27942)) - #52316 (task: remove wrong comments about non-existent LocalWake trait) - #52322 (Update llvm-rebuild-trigger in light of LLVM 7 upgrade) - #52332 (dead-code lint: say "constructed", "called" for structs, functions) Failed merges: r? @ghost
task: remove wrong comments about non-existent LocalWake trait ~~A `LocalWaker` is specifically `!Send `, and the unsafety comment around `LocalWaker::new` only specifies that it be safe to call `wake_local`. One could then accidentally promote a `LocalWaker` into a `Waker`, which is universally `Send`, simply via `Waker::from(local_waker)`. A `LocalWaker` the was built expecting to not be `Send`, such as using `Rc`, could be sent to other threads safely.~~ ~~Separately, though somewhat related, `Context` holds a `&LocalWaker` internally, and exposes a `waker() -> &Waker` method. This simply transmutes the `&LocalWaker` to `&Waker`, which would be unsound, except that you can't "send" a `&Waker`, you'd need to clone it first. Since `UnsafeWake::clone_raw` requires that it return a `Waker`, the transmute is not unsound. The transmuted `LocalWaker` will be promoted to a `Waker` correctly.~~ ~~That would mean that if `UnsafeWake::clone_raw` were to be changed, such as returning `Self` instead of `Waker`, this would no longer be sound. Thus, this also adds a comment to `clone_raw` to remember this.~~ r? @cramertj
Rollup of 17 pull requests Successful merges: - #51962 (Provide llvm-strip in llvm-tools component) - #52003 (Implement `Option::replace` in the core library) - #52156 (Update std::ascii::ASCIIExt deprecation notes) - #52280 (llvm-tools-preview: fix build-manifest) - #52290 (Deny bare trait objects in src/librustc_save_analysis) - #52293 (Deny bare trait objects in librustc_typeck) - #52299 (Deny bare trait objects in src/libserialize) - #52300 (Deny bare trait objects in librustc_target and libtest) - #52302 (Deny bare trait objects in the rest of rust) - #52310 (Backport 1.27.1 release notes to master) - #52315 (Resolve FIXME(#27942)) - #52316 (task: remove wrong comments about non-existent LocalWake trait) - #52322 (Update llvm-rebuild-trigger in light of LLVM 7 upgrade) - #52330 (Don't silently ignore invalid data in target spec) - #52333 (CI: Enable core dump on Linux, and print their stack trace on segfault. ) - #52346 (Fix typo in improper_ctypes suggestion) - #52350 (Bump bootstrap compiler to 1.28.0-beta.10) Failed merges: r? @ghost
A
LocalWakeris specifically!Send, and the unsafety comment aroundLocalWaker::newonly specifies that it be safe to callwake_local.One could then accidentally promote a
LocalWakerinto aWaker, whichis universally
Send, simply viaWaker::from(local_waker). ALocalWakerthe was built expecting to not beSend, such as usingRc, could be sent to other threads safely.Separately, though somewhat related,
Contextholds a&LocalWakerinternally, and exposes a
waker() -> &Wakermethod. This simplytransmutes the
&LocalWakerto&Waker, which would be unsound, exceptthat you can't "send" a
&Waker, you'd need to clone it first. SinceUnsafeWake::clone_rawrequires that it return aWaker, the transmuteis not unsound. The transmuted
LocalWakerwill be promoted to aWakercorrectly.That would mean that ifUnsafeWake::clone_rawwere to be changed, suchas returning
Selfinstead ofWaker, this would no longer be sound.Thus, this also adds a comment to
clone_rawto remember this.r? @cramertj