Skip to content

Commit c0e926c

Browse files
committed
Change has_atomic_cas to no_atomic_cas to implement the first workaround
1 parent 665c32e commit c0e926c

File tree

14 files changed

+259
-32
lines changed

14 files changed

+259
-32
lines changed

futures-channel/build.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,12 @@ fn main() {
1616
}
1717
};
1818

19-
if cfg.probe_expression("core::sync::atomic::AtomicPtr::<()>::compare_exchange") {
20-
println!("cargo:rustc-cfg=has_atomic_cas");
19+
// Note that this is `no_atomic_cas`, not `has_atomic_cas`. This allows to
20+
// treat `cfg(target_has_atomic = "ptr")` as true when the build script
21+
// doesn't run. This is needed for compatibility with non-cargo build
22+
// systems that don't run build scripts.
23+
if !cfg.probe_expression("core::sync::atomic::AtomicPtr::<()>::compare_exchange") {
24+
println!("cargo:rustc-cfg=no_atomic_cas");
2125
}
2226
println!("cargo:rerun-if-changed=build.rs");
2327
}

futures-channel/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
macro_rules! cfg_target_has_atomic {
2424
($($item:item)*) => {$(
25-
#[cfg(has_atomic_cas)]
25+
#[cfg(not(no_atomic_cas))]
2626
$item
2727
)*};
2828
}

futures-core/build.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,12 @@ fn main() {
1616
}
1717
};
1818

19-
if cfg.probe_expression("core::sync::atomic::AtomicPtr::<()>::compare_exchange") {
20-
println!("cargo:rustc-cfg=has_atomic_cas");
19+
// Note that this is `no_atomic_cas`, not `has_atomic_cas`. This allows to
20+
// treat `cfg(target_has_atomic = "ptr")` as true when the build script
21+
// doesn't run. This is needed for compatibility with non-cargo build
22+
// systems that don't run build scripts.
23+
if !cfg.probe_expression("core::sync::atomic::AtomicPtr::<()>::compare_exchange") {
24+
println!("cargo:rustc-cfg=no_atomic_cas");
2125
}
2226
println!("cargo:rerun-if-changed=build.rs");
2327
}
+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#[cfg(has_atomic_cas)]
1+
#[cfg(not(no_atomic_cas))]
22
mod atomic_waker;
3-
#[cfg(has_atomic_cas)]
3+
#[cfg(not(no_atomic_cas))]
44
pub use self::atomic_waker::AtomicWaker;

futures-task/build.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,12 @@ fn main() {
1616
}
1717
};
1818

19-
if cfg.probe_expression("core::sync::atomic::AtomicPtr::<()>::compare_exchange") {
20-
println!("cargo:rustc-cfg=has_atomic_cas");
19+
// Note that this is `no_atomic_cas`, not `has_atomic_cas`. This allows to
20+
// treat `cfg(target_has_atomic = "ptr")` as true when the build script
21+
// doesn't run. This is needed for compatibility with non-cargo build
22+
// systems that don't run build scripts.
23+
if !cfg.probe_expression("core::sync::atomic::AtomicPtr::<()>::compare_exchange") {
24+
println!("cargo:rustc-cfg=no_atomic_cas");
2125
}
2226
println!("cargo:rerun-if-changed=build.rs");
2327
}

futures-task/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ extern crate alloc;
1919

2020
macro_rules! cfg_target_has_atomic {
2121
($($item:item)*) => {$(
22-
#[cfg(has_atomic_cas)]
22+
#[cfg(not(no_atomic_cas))]
2323
$item
2424
)*};
2525
}

futures-task/src/spawn2.rs

+207
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
use crate::{FutureObj, LocalFutureObj};
2+
use core::fmt;
3+
use std::{future::Future, pin::Pin};
4+
5+
/// The `Spawn` trait allows for pushing futures onto an executor that will
6+
/// run them to completion.
7+
pub trait Spawn {
8+
type Handle;
9+
/// An error that occurred during spawning.
10+
type Error;
11+
12+
/// Spawns a future that will be run to completion.
13+
///
14+
/// # Errors
15+
///
16+
/// The executor may be unable to spawn tasks. Spawn errors should
17+
/// represent relatively rare scenarios, such as the executor
18+
/// having been shut down so that it is no longer able to accept
19+
/// tasks.
20+
fn spawn_boxed(
21+
&self,
22+
future: Pin<Box<dyn Future<Output = ()> + Send + 'static>>,
23+
) -> Result<Self::Handle, Self::Error>;
24+
25+
/// Determines whether the executor is able to spawn new tasks.
26+
///
27+
/// This method will return `Ok` when the executor is *likely*
28+
/// (but not guaranteed) to accept a subsequent spawn attempt.
29+
/// Likewise, an `Err` return means that `spawn` is likely, but
30+
/// not guaranteed, to yield an error.
31+
#[inline]
32+
fn status(&self) -> Result<(), Self::Error> {
33+
Ok(())
34+
}
35+
}
36+
37+
/// The `LocalSpawn` is similar to [`Spawn`], but allows spawning futures
38+
/// that don't implement `Send`.
39+
pub trait LocalSpawn {
40+
type Handle;
41+
/// An error that occurred during spawning.
42+
type Error;
43+
44+
/// Spawns a future that will be run to completion.
45+
///
46+
/// # Errors
47+
///
48+
/// The executor may be unable to spawn tasks. Spawn errors should
49+
/// represent relatively rare scenarios, such as the executor
50+
/// having been shut down so that it is no longer able to accept
51+
/// tasks.
52+
fn spawn_local_boxed(
53+
&self,
54+
future: Pin<Box<dyn Future<Output = ()> + Send + 'static>>,
55+
) -> Result<Self::Handle, Self::Error>;
56+
57+
/// Determines whether the executor is able to spawn new tasks.
58+
///
59+
/// This method will return `Ok` when the executor is *likely*
60+
/// (but not guaranteed) to accept a subsequent spawn attempt.
61+
/// Likewise, an `Err` return means that `spawn` is likely, but
62+
/// not guaranteed, to yield an error.
63+
#[inline]
64+
fn status_local(&self) -> Result<(), Self::Error> {
65+
Ok(())
66+
}
67+
}
68+
69+
impl<Sp: ?Sized + Spawn> Spawn for &Sp {
70+
fn spawn_boxed(
71+
&self,
72+
future: Pin<Box<dyn Future<Output = ()> + Send + 'static>>,
73+
) -> Result<Self::Handle, Self::Error> {
74+
Sp::spawn_obj(self, future)
75+
}
76+
77+
fn status(&self) -> Result<(), Self::Error> {
78+
Sp::status(self)
79+
}
80+
}
81+
82+
impl<Sp: ?Sized + Spawn> Spawn for &mut Sp {
83+
fn spawn_boxed(
84+
&self,
85+
future: Pin<Box<dyn Future<Output = ()> + Send + 'static>>,
86+
) -> Result<Self::Handle, Self::Error> {
87+
Sp::spawn_obj(self, future)
88+
}
89+
90+
fn status(&self) -> Result<(), Self::Error> {
91+
Sp::status(self)
92+
}
93+
}
94+
95+
impl<Sp: ?Sized + LocalSpawn> LocalSpawn for &Sp {
96+
fn spawn_local_boxed(
97+
&self,
98+
future: Pin<Box<dyn Future<Output = ()> + Send + 'static>>,
99+
) -> Result<Self::Handle, Self::Error> {
100+
Sp::spawn_local_boxed(self, future)
101+
}
102+
103+
fn status_local(&self) -> Result<(), Self::Error> {
104+
Sp::status_local(self)
105+
}
106+
}
107+
108+
impl<Sp: ?Sized + LocalSpawn> LocalSpawn for &mut Sp {
109+
fn spawn_local_boxed(
110+
&self,
111+
future: Pin<Box<dyn Future<Output = ()> + Send + 'static>>,
112+
) -> Result<Self::Handle, Self::Error> {
113+
Sp::spawn_local_boxed(self, future)
114+
}
115+
116+
fn status_local(&self) -> Result<(), Self::Error> {
117+
Sp::status_local(self)
118+
}
119+
}
120+
121+
#[cfg(feature = "alloc")]
122+
mod if_alloc {
123+
use super::*;
124+
use alloc::{boxed::Box, rc::Rc};
125+
126+
impl<Sp: ?Sized + Spawn> Spawn for Box<Sp> {
127+
fn spawn_boxed(
128+
&self,
129+
future: Pin<Box<dyn Future<Output = ()> + Send + 'static>>,
130+
) -> Result<Self::Handle, Self::Error> {
131+
(**self).spawn_obj(future)
132+
}
133+
134+
fn status(&self) -> Result<(), Self::Error> {
135+
(**self).status()
136+
}
137+
}
138+
139+
impl<Sp: ?Sized + LocalSpawn> LocalSpawn for Box<Sp> {
140+
fn spawn_local_boxed(
141+
&self,
142+
future: Pin<Box<dyn Future<Output = ()> + Send + 'static>>,
143+
) -> Result<Self::Handle, Self::Error> {
144+
(**self).spawn_local_boxed(future)
145+
}
146+
147+
fn status_local(&self) -> Result<(), Self::Error> {
148+
(**self).status_local()
149+
}
150+
}
151+
152+
impl<Sp: ?Sized + Spawn> Spawn for Rc<Sp> {
153+
fn spawn_boxed(
154+
&self,
155+
future: Pin<Box<dyn Future<Output = ()> + Send + 'static>>,
156+
) -> Result<Self::Handle, Self::Error> {
157+
(**self).spawn_obj(future)
158+
}
159+
160+
fn status(&self) -> Result<(), Self::Error> {
161+
(**self).status()
162+
}
163+
}
164+
165+
impl<Sp: ?Sized + LocalSpawn> LocalSpawn for Rc<Sp> {
166+
fn spawn_local_boxed(
167+
&self,
168+
future: Pin<Box<dyn Future<Output = ()> + Send + 'static>>,
169+
) -> Result<Self::Handle, Self::Error> {
170+
(**self).spawn_local_boxed(future)
171+
}
172+
173+
fn status_local(&self) -> Result<(), Self::Error> {
174+
(**self).status_local()
175+
}
176+
}
177+
178+
cfg_target_has_atomic! {
179+
use alloc::sync::Arc;
180+
181+
impl<Sp: ?Sized + Spawn> Spawn for Arc<Sp> {
182+
fn spawn_boxed(
183+
&self,
184+
future: Pin<Box<dyn Future<Output = ()> + Send + 'static>>,
185+
) -> Result<Self::Handle, Self::Error> {
186+
(**self).spawn_obj(future)
187+
}
188+
189+
fn status(&self) -> Result<(), Self::Error> {
190+
(**self).status()
191+
}
192+
}
193+
194+
impl<Sp: ?Sized + LocalSpawn> LocalSpawn for Arc<Sp> {
195+
fn spawn_local_boxed(
196+
&self,
197+
future: Pin<Box<dyn Future<Output = ()> + Send + 'static>>,
198+
) -> Result<Self::Handle, Self::Error> {
199+
(**self).spawn_local_boxed(future)
200+
}
201+
202+
fn status_local(&self) -> Result<(), Self::Error> {
203+
(**self).status_local()
204+
}
205+
}
206+
}
207+
}

futures-util/build.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,12 @@ fn main() {
1616
}
1717
};
1818

19-
if cfg.probe_expression("core::sync::atomic::AtomicPtr::<()>::compare_exchange") {
20-
println!("cargo:rustc-cfg=has_atomic_cas");
19+
// Note that this is `no_atomic_cas`, not `has_atomic_cas`. This allows to
20+
// treat `cfg(target_has_atomic = "ptr")` as true when the build script
21+
// doesn't run. This is needed for compatibility with non-cargo build
22+
// systems that don't run build scripts.
23+
if !cfg.probe_expression("core::sync::atomic::AtomicPtr::<()>::compare_exchange") {
24+
println!("cargo:rustc-cfg=no_atomic_cas");
2125
}
2226
println!("cargo:rerun-if-changed=build.rs");
2327
}

futures-util/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ pub mod __private {
5757

5858
macro_rules! cfg_target_has_atomic {
5959
($($item:item)*) => {$(
60-
#[cfg(has_atomic_cas)]
60+
#[cfg(not(no_atomic_cas))]
6161
$item
6262
)*};
6363
}

futures-util/src/stream/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@ pub use self::stream::ReadyChunks;
3131
#[cfg_attr(docsrs, doc(cfg(feature = "sink")))]
3232
pub use self::stream::Forward;
3333

34-
#[cfg(has_atomic_cas)]
34+
#[cfg(not(no_atomic_cas))]
3535
#[cfg(feature = "alloc")]
3636
pub use self::stream::{BufferUnordered, Buffered, ForEachConcurrent};
3737

38-
#[cfg(has_atomic_cas)]
38+
#[cfg(not(no_atomic_cas))]
3939
#[cfg(feature = "sink")]
4040
#[cfg_attr(docsrs, doc(cfg(feature = "sink")))]
4141
#[cfg(feature = "alloc")]
@@ -53,7 +53,7 @@ pub use self::try_stream::{
5353
#[cfg(feature = "std")]
5454
pub use self::try_stream::IntoAsyncRead;
5555

56-
#[cfg(has_atomic_cas)]
56+
#[cfg(not(no_atomic_cas))]
5757
#[cfg(feature = "alloc")]
5858
pub use self::try_stream::{TryBufferUnordered, TryBuffered, TryForEachConcurrent};
5959

futures-util/src/stream/stream/mod.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -917,7 +917,7 @@ pub trait StreamExt: Stream {
917917
/// fut.await;
918918
/// # })
919919
/// ```
920-
#[cfg(has_atomic_cas)]
920+
#[cfg(not(no_atomic_cas))]
921921
#[cfg(feature = "alloc")]
922922
fn for_each_concurrent<Fut, F>(
923923
self,
@@ -1140,7 +1140,7 @@ pub trait StreamExt: Stream {
11401140
///
11411141
/// This method is only available when the `std` or `alloc` feature of this
11421142
/// library is activated, and it is activated by default.
1143-
#[cfg(has_atomic_cas)]
1143+
#[cfg(not(no_atomic_cas))]
11441144
#[cfg(feature = "alloc")]
11451145
fn buffered(self, n: usize) -> Buffered<Self>
11461146
where
@@ -1185,7 +1185,7 @@ pub trait StreamExt: Stream {
11851185
/// assert_eq!(buffered.next().await, None);
11861186
/// # Ok::<(), i32>(()) }).unwrap();
11871187
/// ```
1188-
#[cfg(has_atomic_cas)]
1188+
#[cfg(not(no_atomic_cas))]
11891189
#[cfg(feature = "alloc")]
11901190
fn buffer_unordered(self, n: usize) -> BufferUnordered<Self>
11911191
where
@@ -1349,7 +1349,7 @@ pub trait StreamExt: Stream {
13491349
/// library is activated, and it is activated by default.
13501350
#[cfg(feature = "sink")]
13511351
#[cfg_attr(docsrs, doc(cfg(feature = "sink")))]
1352-
#[cfg(has_atomic_cas)]
1352+
#[cfg(not(no_atomic_cas))]
13531353
#[cfg(feature = "alloc")]
13541354
fn split<Item>(self) -> (SplitSink<Self, Item>, SplitStream<Self>)
13551355
where

futures-util/src/stream/try_stream/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,7 @@ pub trait TryStreamExt: TryStream {
515515
/// assert_eq!(Err(oneshot::Canceled), fut.await);
516516
/// # })
517517
/// ```
518-
#[cfg(has_atomic_cas)]
518+
#[cfg(not(no_atomic_cas))]
519519
#[cfg(feature = "alloc")]
520520
fn try_for_each_concurrent<Fut, F>(
521521
self,
@@ -836,7 +836,7 @@ pub trait TryStreamExt: TryStream {
836836
/// assert_eq!(buffered.next().await, Some(Err("error in the stream")));
837837
/// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
838838
/// ```
839-
#[cfg(has_atomic_cas)]
839+
#[cfg(not(no_atomic_cas))]
840840
#[cfg(feature = "alloc")]
841841
fn try_buffer_unordered(self, n: usize) -> TryBufferUnordered<Self>
842842
where
@@ -912,7 +912,7 @@ pub trait TryStreamExt: TryStream {
912912
/// assert_eq!(buffered.next().await, Some(Err("error in the stream")));
913913
/// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
914914
/// ```
915-
#[cfg(has_atomic_cas)]
915+
#[cfg(not(no_atomic_cas))]
916916
#[cfg(feature = "alloc")]
917917
fn try_buffered(self, n: usize) -> TryBuffered<Self>
918918
where

0 commit comments

Comments
 (0)