Skip to content

Commit 1f9aa13

Browse files
Split libcore/task.rs into submodules
1 parent 764232c commit 1f9aa13

File tree

7 files changed

+401
-294
lines changed

7 files changed

+401
-294
lines changed

src/libcore/task/context.rs

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![unstable(feature = "futures_api",
12+
reason = "futures in libcore are unstable",
13+
issue = "50547")]
14+
15+
use fmt;
16+
use super::{Executor, Waker, LocalWaker};
17+
18+
/// Information about the currently-running task.
19+
///
20+
/// Contexts are always tied to the stack, since they are set up specifically
21+
/// when performing a single `poll` step on a task.
22+
pub struct Context<'a> {
23+
local_waker: &'a LocalWaker,
24+
executor: &'a mut Executor,
25+
}
26+
27+
impl<'a> fmt::Debug for Context<'a> {
28+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
29+
f.debug_struct("Context")
30+
.finish()
31+
}
32+
}
33+
34+
impl<'a> Context<'a> {
35+
/// Create a new task `Context` with the provided `local_waker`, `waker`, and `executor`.
36+
#[inline]
37+
pub fn new(local_waker: &'a LocalWaker, executor: &'a mut Executor) -> Context<'a> {
38+
Context {
39+
local_waker,
40+
executor,
41+
}
42+
}
43+
44+
/// Get the `LocalWaker` associated with the current task.
45+
#[inline]
46+
pub fn local_waker(&self) -> &'a LocalWaker {
47+
self.local_waker
48+
}
49+
50+
/// Get the `Waker` associated with the current task.
51+
#[inline]
52+
pub fn waker(&self) -> &'a Waker {
53+
unsafe { &*(self.local_waker as *const LocalWaker as *const Waker) }
54+
}
55+
56+
/// Get the default executor associated with this task.
57+
///
58+
/// This method is useful primarily if you want to explicitly handle
59+
/// spawn failures.
60+
#[inline]
61+
pub fn executor(&mut self) -> &mut Executor {
62+
self.executor
63+
}
64+
65+
/// Produce a context like the current one, but using the given waker instead.
66+
///
67+
/// This advanced method is primarily used when building "internal
68+
/// schedulers" within a task, where you want to provide some customized
69+
/// wakeup logic.
70+
#[inline]
71+
pub fn with_waker<'b>(&'b mut self, local_waker: &'b LocalWaker) -> Context<'b> {
72+
Context {
73+
local_waker,
74+
executor: self.executor,
75+
}
76+
}
77+
78+
/// Produce a context like the current one, but using the given executor
79+
/// instead.
80+
///
81+
/// This advanced method is primarily used when building "internal
82+
/// schedulers" within a task.
83+
#[inline]
84+
pub fn with_executor<'b, E>(&'b mut self, executor: &'b mut E) -> Context<'b>
85+
where E: Executor
86+
{
87+
Context {
88+
local_waker: self.local_waker,
89+
executor: executor,
90+
}
91+
}
92+
}

src/libcore/task/executor.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![unstable(feature = "futures_api",
12+
reason = "futures in libcore are unstable",
13+
issue = "50547")]
14+
15+
use super::{TaskObj, SpawnObjError, SpawnErrorKind};
16+
17+
/// A task executor.
18+
///
19+
/// A *task* is a `()`-producing async value that runs at the top level, and will
20+
/// be `poll`ed until completion. It's also the unit at which wake-up
21+
/// notifications occur. Executors, such as thread pools, allow tasks to be
22+
/// spawned and are responsible for putting tasks onto ready queues when
23+
/// they are woken up, and polling them when they are ready.
24+
pub trait Executor {
25+
/// Spawn the given task, polling it until completion.
26+
///
27+
/// # Errors
28+
///
29+
/// The executor may be unable to spawn tasks, either because it has
30+
/// been shut down or is resource-constrained.
31+
fn spawn_obj(&mut self, task: TaskObj) -> Result<(), SpawnObjError>;
32+
33+
/// Determine whether the executor is able to spawn new tasks.
34+
///
35+
/// # Returns
36+
///
37+
/// An `Ok` return means the executor is *likely* (but not guaranteed)
38+
/// to accept a subsequent spawn attempt. Likewise, an `Err` return
39+
/// means that `spawn` is likely, but not guaranteed, to yield an error.
40+
#[inline]
41+
fn status(&self) -> Result<(), SpawnErrorKind> {
42+
Ok(())
43+
}
44+
}

src/libcore/task/mod.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![unstable(feature = "futures_api",
12+
reason = "futures in libcore are unstable",
13+
issue = "50547")]
14+
15+
//! Types and Traits for working with asynchronous tasks.
16+
17+
mod context;
18+
pub use self::context::Context;
19+
20+
mod executor;
21+
pub use self::executor::Executor;
22+
23+
mod poll;
24+
pub use self::poll::Poll;
25+
26+
mod spawn_error;
27+
pub use self::spawn_error::{SpawnErrorKind, SpawnObjError};
28+
29+
mod task;
30+
pub use self::task::{TaskObj, UnsafeTask};
31+
32+
mod wake;
33+
pub use self::wake::{Waker, LocalWaker, UnsafeWake};

src/libcore/task/poll.rs

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![unstable(feature = "futures_api",
12+
reason = "futures in libcore are unstable",
13+
issue = "50547")]
14+
15+
/// Indicates whether a value is available or if the current task has been
16+
/// scheduled to receive a wakeup instead.
17+
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
18+
pub enum Poll<T> {
19+
/// Represents that a value is immediately ready.
20+
Ready(T),
21+
22+
/// Represents that a value is not ready yet.
23+
///
24+
/// When a function returns `Pending`, the function *must* also
25+
/// ensure that the current task is scheduled to be awoken when
26+
/// progress can be made.
27+
Pending,
28+
}
29+
30+
impl<T> Poll<T> {
31+
/// Change the ready value of this `Poll` with the closure provided
32+
pub fn map<U, F>(self, f: F) -> Poll<U>
33+
where F: FnOnce(T) -> U
34+
{
35+
match self {
36+
Poll::Ready(t) => Poll::Ready(f(t)),
37+
Poll::Pending => Poll::Pending,
38+
}
39+
}
40+
41+
/// Returns whether this is `Poll::Ready`
42+
pub fn is_ready(&self) -> bool {
43+
match *self {
44+
Poll::Ready(_) => true,
45+
Poll::Pending => false,
46+
}
47+
}
48+
49+
/// Returns whether this is `Poll::Pending`
50+
pub fn is_pending(&self) -> bool {
51+
!self.is_ready()
52+
}
53+
}
54+
55+
impl<T, E> Poll<Result<T, E>> {
56+
/// Change the success value of this `Poll` with the closure provided
57+
pub fn map_ok<U, F>(self, f: F) -> Poll<Result<U, E>>
58+
where F: FnOnce(T) -> U
59+
{
60+
match self {
61+
Poll::Ready(Ok(t)) => Poll::Ready(Ok(f(t))),
62+
Poll::Ready(Err(e)) => Poll::Ready(Err(e)),
63+
Poll::Pending => Poll::Pending,
64+
}
65+
}
66+
67+
/// Change the error value of this `Poll` with the closure provided
68+
pub fn map_err<U, F>(self, f: F) -> Poll<Result<T, U>>
69+
where F: FnOnce(E) -> U
70+
{
71+
match self {
72+
Poll::Ready(Ok(t)) => Poll::Ready(Ok(t)),
73+
Poll::Ready(Err(e)) => Poll::Ready(Err(f(e))),
74+
Poll::Pending => Poll::Pending,
75+
}
76+
}
77+
}
78+
79+
impl<T> From<T> for Poll<T> {
80+
fn from(t: T) -> Poll<T> {
81+
Poll::Ready(t)
82+
}
83+
}

src/libcore/task/spawn_error.rs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![unstable(feature = "futures_api",
12+
reason = "futures in libcore are unstable",
13+
issue = "50547")]
14+
15+
use fmt;
16+
use super::TaskObj;
17+
18+
/// Provides the reason that an executor was unable to spawn.
19+
pub struct SpawnErrorKind {
20+
_hidden: (),
21+
}
22+
23+
impl fmt::Debug for SpawnErrorKind {
24+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
25+
f.debug_tuple("SpawnErrorKind")
26+
.field(&"shutdown")
27+
.finish()
28+
}
29+
}
30+
31+
impl SpawnErrorKind {
32+
/// Spawning is failing because the executor has been shut down.
33+
pub fn shutdown() -> SpawnErrorKind {
34+
SpawnErrorKind { _hidden: () }
35+
}
36+
37+
/// Check whether this error is the `shutdown` error.
38+
pub fn is_shutdown(&self) -> bool {
39+
true
40+
}
41+
}
42+
43+
/// The result of a failed spawn
44+
#[derive(Debug)]
45+
pub struct SpawnObjError {
46+
/// The kind of error
47+
pub kind: SpawnErrorKind,
48+
49+
/// The task for which spawning was attempted
50+
pub task: TaskObj,
51+
}

0 commit comments

Comments
 (0)