Files
archy/core/target/debug/deps/libatomic_waker-ea44e3625ec8e406.rmeta
T

32 lines
13 KiB
Plaintext
Raw Normal View History

2026-01-24 22:59:20 +00:00
rust
3#rustc 1.93.0 (254b59607 2026-01-19)Á³VOÐêùÿ²?ÑL¼§Ì±-a7a40eb546f9e2b0Áë&Gf·Ã ¬ëñq:¤»b-bb76018b1173caf6Áb\§portable-atomicÁŒþÜô³ AtomicWakerÁ  wakerÁWAITINGÁ REGISTERINGÁWAKINGÁ 
AssertSyncÁregisterÁ wakeÁtakeÁ>Í






º~º~¯»~ÿ~âj4óÐÀWÄ  æ 
ÿIx·u{ùIà`ï¨âïïº~    Äà`¨â0b01Á0b10ÁÌàF
„àF
¸¸<ñF 7¬ŽG$žG
ø°»%
,|ŽG
Î.ø°ú°û°Ðü°ý°þ°ìHˈXêE>» ¢Gü¿Fo
  ­G´Gü«E‰ï$ÁE®¸®¸b¯¸ÓZiVwƒ'_Ç.Ç.
UnsafeCellÁÉ.˜¸+ö)=ê „9Û´c´c¢ ³¨Ç.ÍÅÁ]F4í×´FØ´G<õÕ´GÖ´üÓ´üÔ´¯º~ b\᮸
ü§ü>; `futures::task::AtomicWaker` extracted into its own crate.Á?ËtC # FeaturesÁRËüVGD This crate adds a feature, `portable-atomic`, which uses a polyfillÁüžHE from the [`portable-atomic`] crate in order to provide functionalityÁüçNK to targets without atomics. See the [`README`] for the [`portable-atomic`]Áü¶0- crate for more information on how to use it.ÁçËüëA> [`portable-atomic`]: https://crates.io/crates/portable-atomicÁü­[X [`README`]: https://github.com/taiki-e/portable-atomic/blob/main/README.md#optional-cfgÁ¡˜  ˜8µ„¡ ²7ahttps://raw.githubusercontent.com/smol-rs/smol/master/assets/images/logo_fullsize_transparent.pngÁü´cü•¡ž ¡ 8 µ7Üü·cü› ³¨Ç.ÍÁ]F
×´FØ´G
Õ´GÖ´ü
Ó´ü Ô´¯
2026-01-24 22:59:20 +00:00
º~ b ®¸
´£L¿¨üÎ8ººŸ¢~ŒŒ`üÍV´Ùüµ0- A synchronization primitive for task wakeup.ÁæËüêIF Sometimes the task interested in a given event will change over time.Áü´ NK An `AtomicWaker` can coordinate concurrent notifications with the consumerÁüƒ
LI potentially "updating" the underlying task to wake up. This is useful inÁüÐ
JG scenarios where a computation completes in another thread and wants toÁü› PM notify the consumer, but the consumer is in the process of being migrated toÁ¼ì  a new logical task.Á Ëüˆ PM Consumers should call `register` before checking the result of a computationÁüÙ JG and producers should call `wake` after producing the computation (thisÁü¤
LI differs from the usual `thread::park` pattern). It is also permitted forÁüñ
GD `wake` to be called **before** `register`. This results in a no-op.Á¹Ëü½QN A single `AtomicWaker` may be reused for any number of calls to `register` orÁ\ `wake`.ÁˬŸ # Memory orderingÁµËü¹JG Calling `register` "acquires" all memory "released" by calls to `wake`Áü„GD before the call to `register`. Later calls to `wake` will wake theÁüÌPM registered waker (on contention this wake might be triggered in `register`).ÁËü¡OL For concurrent calls to `register` (should be avoided) the ordering is onlyÁüñ$! guaranteed for the winning call.ÁË # ExamplesÁ©Ëü­NK Here is a simple example providing a `Flag` that can be signalled manuallyÁ¬ü when it is ready.ÁË<– ```Áüž  use futures::future::Future;Áü¿41 use futures::task::{Context, Poll, AtomicWaker};Á¼ô use std::sync::Arc;ÁüŒ&# use std::sync::atomic::AtomicBool;Áü³-* use std::sync::atomic::Ordering::Relaxed;Á´á use std::pin::Pin;ÁøË”ü struct Inner {ÁÜ waker: AtomicWaker,ÁÄ« set: AtomicBool,ÁÊˤΠ#[derive(Clone)]Áäã struct Flag(Arc<Inner>);ÁË|„ impl Flag {Áô” pub fn new() -> Self {Áü³! Flag(Arc::new(Inner {ÁüÕ*' waker: AtomicWaker::new(),Áü€,) set: AtomicBool::new(false),Á|­ }))ÁÇËôË pub fn signal(&self) {Áüê,) self.0.set.store(true, Relaxed);Áü—  self.0.waker.wake();ÁL¸º%ñ"ÈËÔÌ impl Future for Flag {ÁÌç type Output = ();ÁËü…IF fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {ÁüÏA> // quick check to avoid registration if already done.Áü‘)& if self.0.set.load(Relaxed) {Áü»'$ return Poll::Ready(());Á
ñËüõ.+ self.0.waker.register(cx.waker());Á¤Ëü¨KH // Need to check condition **after** `register` to avoid a raceÁüôA> // condition that would result in lost notifications.Áü¶)æ(üà Poll::Ready(())Á¤€ } else {Áì• Poll::PendingÁÇ)º%ñ"òïIx·u{ùI
”ö  èüŽ   ž ¤ƒC<‰CÄåC\ëCœÖD4ÜD„óDïÔ«EäŠE Create an `AtomicWaker`.Á¸Eï
´÷ETýEªâÌ÷EŒ0$‰F„0%0„0/0%Ì™F»ü©W%üºG:7 Registers the waker to be notified on calls to `wake`.ÁùGËüHKH The new task will take place of any previous tasks that were registeredÁüÑHJG by previous calls to `register`. Any calls to `wake` that happen afterÁü IHE a call to `register` (as defined by the memory ordering rules), willÁüíILI notify the `register` caller's task and deregister the waker from futureÁü¾JIF notifications. Because of this, callers should ensure `register` getsÁüŒKC@ invoked with a new `Waker` **each** time they require a wakeup.ÁÔKËüÜKJG It is safe to call `register` with multiple other threads concurrentlyÁü«LGD calling `wake`. This will result in the `register` caller's currentÁì÷L task being notified once.Á™MËü¡MKH This function is safe to call concurrently, but this is generally a badÁüñMKH idea. Concurrent calls to `register` will attempt to register differentÁüÁNLI tasks to be notified. One of the callers will win and have its task set,Áü’O>; but there is no guarantee as to which caller will succeed.ÁÕOËtÝOÒðOËüøO<9 Here is how `register` is used when implementing a flag.Á¹PË<ÁPòüÍP üòP4« ü«Q&‡!üÖQ-¶!´ˆRë!£RËŒ«R struct Flag {ÁÜÁR®"ÄáRÑ",þRñ"ˆSËÔSû&̯S'ÍSËüÕSIÊ'ü£TKH // Register **before** checking `set` to avoid a race conditionÁüóT74 // that would result in lost notifications.Áü¯U,) self.waker.register(cx.waker());ÁàUËüèU'$ if self.set.load(Relaxed) {Áü”VÔ+¤¸Vû+ìÑV—,lóVÇ)L…Wº%,“Wñ"<WòD°W  ï  » ¹W
$ºWÿ,ÀWÙX<closure_kind>Á<closure_signature>Á<upvars>Áö>”¢~ü”}:7 Calls `wake` on the last `Waker` passed to `register`.ÁÓ}ËüÛ}B? If `register` has not been called yet, then this does nothing.Á$©~! ö> ®~