task: remove wrong comments about non-existent LocalWake trait#52316
task: remove wrong comments about non-existent LocalWake trait#52316bors merged 1 commit intorust-lang:masterfrom
Conversation
src/libcore/task/wake.rs
Outdated
There was a problem hiding this comment.
I also removed these comments, since there is no LocalWake trait.
There was a problem hiding this comment.
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