Skip to content

Commit a93a417

Browse files
committed
Merge rayon-rs#698 (jClaireCodesStuff:issue-697)
2 parents 9fea4bb + cf0bb96 commit a93a417

File tree

3 files changed

+114
-12
lines changed

3 files changed

+114
-12
lines changed

rayon-futures/src/compile_fail/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
// These modules contain `compile_fail` doc tests.
22
mod future_escape;
3+
mod non_send_item;
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*! ```compile_fail,E0277
2+
extern crate futures;
3+
extern crate rayon_core;
4+
5+
use std::marker::PhantomData;
6+
use futures::future::poll_fn;
7+
use futures::Poll;
8+
use futures::Async;
9+
use futures::Future;
10+
use rayon_futures::ScopeFutureExt;
11+
use rayon_core::scope;
12+
use rayon_core::ThreadPool;
13+
14+
let evil_future = poll_fn(|| Ok(Async::Ready(PhantomData::<*mut ()>)) );
15+
let pool = ThreadPool::global();
16+
17+
scope(|s| {
18+
let f = s.spawn_future(evil_future); //~ ERROR
19+
let _: Result<_, ()> = f.rayon_wait();
20+
} );
21+
``` */
22+
23+
// Original test case:
24+
25+
/* #[test]
26+
fn non_send_item() {
27+
use std::marker::PhantomData;
28+
use std::thread;
29+
use futures::future::poll_fn;
30+
31+
struct TattleTale {
32+
id: thread::ThreadId,
33+
not_send: PhantomData<*mut ()>
34+
}
35+
36+
impl Drop for TattleTale {
37+
fn drop(&mut self) {
38+
let drop_id = thread::current().id();
39+
assert_eq!(self.id, drop_id);
40+
}
41+
}
42+
43+
let evil_future_factory = || { poll_fn(|| {
44+
let evil_item = TattleTale {
45+
id: thread::current().id(),
46+
not_send: PhantomData,
47+
};
48+
return Ok(Async::Ready(evil_item));
49+
} ) };
50+
51+
let pool = ThreadPool::global();
52+
53+
scope(|s| {
54+
let futures: Vec<_> = (0..1000)
55+
.map(|_: i32| s.spawn_future(evil_future_factory()))
56+
.collect();
57+
58+
for f in futures {
59+
let _: Result<_, ()> = f.rayon_wait();
60+
}
61+
} );
62+
} */

rayon-futures/src/lib.rs

Lines changed: 51 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ const STATE_COMPLETE: usize = 4;
3434
pub trait ScopeFutureExt<'scope> {
3535
fn spawn_future<F>(&self, future: F) -> RayonFuture<F::Item, F::Error>
3636
where
37-
F: Future + Send + 'scope;
37+
F: Future + Send + 'scope,
38+
<F as Future>::Item: Send,
39+
<F as Future>::Error: Send;
3840
}
3941

4042
impl<'scope, T> ScopeFutureExt<'scope> for T
@@ -44,6 +46,8 @@ where
4446
fn spawn_future<F>(&self, future: F) -> RayonFuture<F::Item, F::Error>
4547
where
4648
F: Future + Send + 'scope,
49+
<F as Future>::Item: Send,
50+
<F as Future>::Error: Send,
4751
{
4852
let inner = ScopeFuture::spawn(future, self.to_scope_handle());
4953

@@ -136,6 +140,8 @@ impl<T, E> fmt::Debug for RayonFuture<T, E> {
136140
struct ScopeFuture<'scope, F, S>
137141
where
138142
F: Future + Send + 'scope,
143+
<F as Future>::Item: Send,
144+
<F as Future>::Error: Send,
139145
S: ScopeHandle<'scope>,
140146
{
141147
state: AtomicUsize,
@@ -149,6 +155,8 @@ type CUError<F> = <CU<F> as Future>::Error;
149155
struct ScopeFutureContents<'scope, F, S>
150156
where
151157
F: Future + Send + 'scope,
158+
<F as Future>::Item: Send,
159+
<F as Future>::Error: Send,
152160
S: ScopeHandle<'scope>,
153161
{
154162
spawn: Option<Spawn<CU<F>>>,
@@ -160,7 +168,7 @@ where
160168
// the counter in the scope; since the scope doesn't terminate until
161169
// counter reaches zero, and we hold a ref in this counter, we are
162170
// assured that this pointer remains valid
163-
scope: Option<S>,
171+
scope: Option<ScopeHandleSend<'scope, S>>,
164172

165173
waiting_task: Option<Task>,
166174
result: Poll<CUItem<F>, CUError<F>>,
@@ -171,6 +179,8 @@ where
171179
impl<'scope, F, S> fmt::Debug for ScopeFutureContents<'scope, F, S>
172180
where
173181
F: Future + Send + 'scope,
182+
<F as Future>::Item: Send,
183+
<F as Future>::Error: Send,
174184
S: ScopeHandle<'scope>,
175185
{
176186
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
@@ -183,11 +193,15 @@ where
183193
struct ArcScopeFuture<'scope, F, S>(Arc<ScopeFuture<'scope, F, S>>)
184194
where
185195
F: Future + Send + 'scope,
196+
<F as Future>::Item: Send,
197+
<F as Future>::Error: Send,
186198
S: ScopeHandle<'scope>;
187199

188200
impl<'scope, F, S> Clone for ArcScopeFuture<'scope, F, S>
189201
where
190202
F: Future + Send + 'scope,
203+
<F as Future>::Item: Send,
204+
<F as Future>::Error: Send,
191205
S: ScopeHandle<'scope>,
192206
{
193207
fn clone(&self) -> Self {
@@ -198,6 +212,8 @@ where
198212
impl<'scope, F, S> Notify for ArcScopeFuture<'scope, F, S>
199213
where
200214
F: Future + Send + 'scope,
215+
<F as Future>::Item: Send,
216+
<F as Future>::Error: Send,
201217
S: ScopeHandle<'scope>,
202218
{
203219
fn notify(&self, id: usize) {
@@ -225,6 +241,8 @@ unsafe impl<'scope, F, S> Sync for ScopeFutureWrapped<'scope, F, S> {}
225241
impl<'scope, F, S> Notify for ScopeFutureWrapped<'scope, F, S>
226242
where
227243
F: Future + Send + 'scope,
244+
<F as Future>::Item: Send,
245+
<F as Future>::Error: Send,
228246
S: ScopeHandle<'scope>,
229247
{
230248
fn notify(&self, id: usize) {
@@ -264,6 +282,8 @@ where
264282
unsafe impl<'scope, F, S> UnsafeNotify for ScopeFutureWrapped<'scope, F, S>
265283
where
266284
F: Future + Send + 'scope,
285+
<F as Future>::Item: Send,
286+
<F as Future>::Error: Send,
267287
S: ScopeHandle<'scope>,
268288
{
269289
unsafe fn clone_raw(&self) -> NotifyHandle {
@@ -285,6 +305,8 @@ where
285305
impl<'scope, F, S> From<ArcScopeFuture<'scope, F, S>> for NotifyHandle
286306
where
287307
F: Future + Send + 'scope,
308+
<F as Future>::Item: Send,
309+
<F as Future>::Error: Send,
288310
S: ScopeHandle<'scope>,
289311
{
290312
fn from(rc: ArcScopeFuture<'scope, F, S>) -> NotifyHandle {
@@ -309,22 +331,31 @@ where
309331
}
310332

311333
// Assert that the `*const` is safe to transmit between threads:
312-
unsafe impl<'scope, F, S> Send for ScopeFuture<'scope, F, S>
313-
where
314-
F: Future + Send + 'scope,
315-
S: ScopeHandle<'scope>,
316-
{
317-
}
318-
unsafe impl<'scope, F, S> Sync for ScopeFuture<'scope, F, S>
334+
struct ScopeHandleSend<'s, S: ScopeHandle<'s>>(S, PhantomData<&'s ()>);
335+
unsafe impl<'scope, S> Send for ScopeHandleSend<'scope, S> where S: ScopeHandle<'scope> {}
336+
impl<'scope, S> ScopeHandleSend<'scope, S>
319337
where
320-
F: Future + Send + 'scope,
321338
S: ScopeHandle<'scope>,
322339
{
340+
unsafe fn assert_send(s: S) -> Self {
341+
ScopeHandleSend(s, PhantomData)
342+
}
343+
unsafe fn spawn_task<T: RayonTask + 'scope>(&self, task: Arc<T>) {
344+
self.0.spawn_task(task);
345+
}
346+
fn panicked(self, err: Box<Any + Send>) {
347+
self.0.panicked(err);
348+
}
349+
fn ok(self) {
350+
self.0.ok();
351+
}
323352
}
324353

325354
impl<'scope, F, S> ScopeFuture<'scope, F, S>
326355
where
327356
F: Future + Send + 'scope,
357+
<F as Future>::Item: Send,
358+
<F as Future>::Error: Send,
328359
S: ScopeHandle<'scope>,
329360
{
330361
fn spawn(future: F, scope: S) -> Arc<Self> {
@@ -338,7 +369,7 @@ where
338369
contents: Mutex::new(ScopeFutureContents {
339370
spawn: None,
340371
this: None,
341-
scope: Some(scope),
372+
scope: unsafe { Some(ScopeHandleSend::assert_send(scope)) },
342373
waiting_task: None,
343374
result: Ok(Async::NotReady),
344375
canceled: false,
@@ -466,6 +497,8 @@ where
466497
impl<'scope, F, S> Notify for ScopeFuture<'scope, F, S>
467498
where
468499
F: Future + Send + 'scope,
500+
<F as Future>::Item: Send,
501+
<F as Future>::Error: Send,
469502
S: ScopeHandle<'scope>,
470503
{
471504
fn notify(&self, _: usize) {
@@ -476,6 +509,8 @@ where
476509
impl<'scope, F, S> RayonTask for ScopeFuture<'scope, F, S>
477510
where
478511
F: Future + Send + 'scope,
512+
<F as Future>::Item: Send,
513+
<F as Future>::Error: Send,
479514
S: ScopeHandle<'scope>,
480515
{
481516
fn execute(this: Arc<Self>) {
@@ -510,6 +545,8 @@ where
510545
impl<'scope, F, S> ScopeFutureContents<'scope, F, S>
511546
where
512547
F: Future + Send + 'scope,
548+
<F as Future>::Item: Send,
549+
<F as Future>::Error: Send,
513550
S: ScopeHandle<'scope>,
514551
{
515552
fn poll(&mut self) -> Poll<CUItem<F>, CUError<F>> {
@@ -578,7 +615,9 @@ trait ScopeFutureTrait<T, E>: Send + Sync {
578615

579616
impl<'scope, F, S> ScopeFutureTrait<CUItem<F>, CUError<F>> for ScopeFuture<'scope, F, S>
580617
where
581-
F: Future + Send,
618+
F: Future + Send + 'scope,
619+
<F as Future>::Item: Send,
620+
<F as Future>::Error: Send,
582621
S: ScopeHandle<'scope>,
583622
{
584623
fn probe(&self) -> bool {

0 commit comments

Comments
 (0)