Skip to content

Commit 8cea09d

Browse files
author
Stjepan Glavina
committed
Update async-task
1 parent 184185a commit 8cea09d

File tree

3 files changed

+65
-49
lines changed

3 files changed

+65
-49
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ categories = ["asynchronous", "concurrency"]
1313
readme = "README.md"
1414

1515
[dependencies]
16-
async-task = { path = "../async-task" }
16+
async-task = "4.0.0"
1717
concurrent-queue = "1.2.2"
1818
fastrand = "1.3.4"
1919
futures-lite = "1.0.0"

examples/priority.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,23 @@ enum Priority {
1818
/// An executor with task priorities.
1919
///
2020
/// Tasks with lower priorities only get polled when there are no tasks with higher priorities.
21-
struct PriorityExecutor<'a> {
22-
ex: [Executor<'a>; 3],
21+
struct PriorityExecutor {
22+
ex: [Executor; 3],
2323
}
2424

25-
impl<'a> PriorityExecutor<'a> {
25+
impl PriorityExecutor {
2626
/// Creates a new executor.
27-
const fn new() -> PriorityExecutor<'a> {
27+
const fn new() -> PriorityExecutor {
2828
PriorityExecutor {
2929
ex: [Executor::new(), Executor::new(), Executor::new()],
3030
}
3131
}
3232

3333
/// Spawns a task with the given priority.
34-
fn spawn<T: Send + 'a>(
34+
fn spawn<T: Send + 'static>(
3535
&self,
3636
priority: Priority,
37-
future: impl Future<Output = T> + Send + 'a,
37+
future: impl Future<Output = T> + Send + 'static,
3838
) -> Task<T> {
3939
self.ex[priority as usize].spawn(future)
4040
}
@@ -59,7 +59,7 @@ impl<'a> PriorityExecutor<'a> {
5959
}
6060

6161
fn main() {
62-
static EX: PriorityExecutor<'_> = PriorityExecutor::new();
62+
static EX: PriorityExecutor = PriorityExecutor::new();
6363

6464
// Spawn a thread running the executor forever.
6565
thread::spawn(|| future::block_on(EX.run()));

src/lib.rs

Lines changed: 57 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -61,18 +61,14 @@ pub use async_task::Task;
6161
/// }));
6262
/// ```
6363
#[derive(Debug)]
64-
pub struct Executor<'a> {
64+
pub struct Executor {
6565
state: once_cell::sync::OnceCell<Arc<State>>,
66-
_marker: PhantomData<std::cell::UnsafeCell<&'a ()>>,
6766
}
6867

69-
unsafe impl Send for Executor<'_> {}
70-
unsafe impl Sync for Executor<'_> {}
68+
impl UnwindSafe for Executor {}
69+
impl RefUnwindSafe for Executor {}
7170

72-
impl UnwindSafe for Executor<'_> {}
73-
impl RefUnwindSafe for Executor<'_> {}
74-
75-
impl<'a> Executor<'a> {
71+
impl Executor {
7672
/// Creates a new executor.
7773
///
7874
/// # Examples
@@ -82,10 +78,9 @@ impl<'a> Executor<'a> {
8278
///
8379
/// let ex = Executor::new();
8480
/// ```
85-
pub const fn new() -> Executor<'a> {
81+
pub const fn new() -> Executor {
8682
Executor {
8783
state: once_cell::sync::OnceCell::new(),
88-
_marker: PhantomData,
8984
}
9085
}
9186

@@ -102,8 +97,22 @@ impl<'a> Executor<'a> {
10297
/// println!("Hello world");
10398
/// });
10499
/// ```
105-
pub fn spawn<T: Send + 'a>(&self, future: impl Future<Output = T> + Send + 'a) -> Task<T> {
106-
unsafe { self.spawn_unchecked(future) }
100+
pub fn spawn<T: Send + 'static>(
101+
&self,
102+
future: impl Future<Output = T> + Send + 'static,
103+
) -> Task<T> {
104+
let mut active = self.state().active.lock().unwrap();
105+
let index = active.next_vacant();
106+
let state = self.state().clone();
107+
let future = async move {
108+
let _guard = CallOnDrop(move || drop(state.active.lock().unwrap().remove(index)));
109+
future.await
110+
};
111+
112+
let (runnable, task) = async_task::spawn(future, self.schedule());
113+
active.insert(runnable.waker());
114+
runnable.schedule();
115+
task
107116
}
108117

109118
/// Attempts to run a task if at least one is scheduled.
@@ -211,24 +220,9 @@ impl<'a> Executor<'a> {
211220
fn state(&self) -> &Arc<State> {
212221
self.state.get_or_init(|| Arc::new(State::new()))
213222
}
214-
215-
unsafe fn spawn_unchecked<T>(&self, future: impl Future<Output = T>) -> Task<T> {
216-
let mut active = self.state().active.lock().unwrap();
217-
let index = active.next_vacant();
218-
let state = self.state().clone();
219-
let future = async move {
220-
let _guard = CallOnDrop(move || drop(state.active.lock().unwrap().remove(index)));
221-
future.await
222-
};
223-
224-
let (runnable, task) = async_task::spawn_unchecked(future, self.schedule());
225-
active.insert(runnable.waker());
226-
runnable.schedule();
227-
task
228-
}
229223
}
230224

231-
impl Drop for Executor<'_> {
225+
impl Drop for Executor {
232226
fn drop(&mut self) {
233227
if let Some(state) = self.state.get() {
234228
let mut active = state.active.lock().unwrap();
@@ -244,8 +238,8 @@ impl Drop for Executor<'_> {
244238
}
245239
}
246240

247-
impl<'a> Default for Executor<'a> {
248-
fn default() -> Executor<'a> {
241+
impl Default for Executor {
242+
fn default() -> Executor {
249243
Executor::new()
250244
}
251245
}
@@ -267,18 +261,18 @@ impl<'a> Default for Executor<'a> {
267261
/// }));
268262
/// ```
269263
#[derive(Debug)]
270-
pub struct LocalExecutor<'a> {
264+
pub struct LocalExecutor {
271265
/// The inner executor.
272-
inner: once_cell::unsync::OnceCell<Executor<'a>>,
266+
inner: once_cell::unsync::OnceCell<Executor>,
273267

274268
/// Make sure the type is `!Send` and `!Sync`.
275269
_marker: PhantomData<Rc<()>>,
276270
}
277271

278-
impl UnwindSafe for LocalExecutor<'_> {}
279-
impl RefUnwindSafe for LocalExecutor<'_> {}
272+
impl UnwindSafe for LocalExecutor {}
273+
impl RefUnwindSafe for LocalExecutor {}
280274

281-
impl<'a> LocalExecutor<'a> {
275+
impl LocalExecutor {
282276
/// Creates a single-threaded executor.
283277
///
284278
/// # Examples
@@ -288,7 +282,7 @@ impl<'a> LocalExecutor<'a> {
288282
///
289283
/// let local_ex = LocalExecutor::new();
290284
/// ```
291-
pub const fn new() -> LocalExecutor<'a> {
285+
pub const fn new() -> LocalExecutor {
292286
LocalExecutor {
293287
inner: once_cell::unsync::OnceCell::new(),
294288
_marker: PhantomData,
@@ -308,8 +302,19 @@ impl<'a> LocalExecutor<'a> {
308302
/// println!("Hello world");
309303
/// });
310304
/// ```
311-
pub fn spawn<T: 'a>(&self, future: impl Future<Output = T> + 'a) -> Task<T> {
312-
unsafe { self.inner().spawn_unchecked(future) }
305+
pub fn spawn<T: 'static>(&self, future: impl Future<Output = T> + 'static) -> Task<T> {
306+
let mut active = self.inner().state().active.lock().unwrap();
307+
let index = active.next_vacant();
308+
let state = self.inner().state().clone();
309+
let future = async move {
310+
let _guard = CallOnDrop(move || drop(state.active.lock().unwrap().remove(index)));
311+
future.await
312+
};
313+
314+
let (runnable, task) = async_task::spawn_local(future, self.schedule());
315+
active.insert(runnable.waker());
316+
runnable.schedule();
317+
task
313318
}
314319

315320
/// Attempts to run a task if at least one is scheduled.
@@ -375,14 +380,24 @@ impl<'a> LocalExecutor<'a> {
375380
self.inner().run(future).await
376381
}
377382

383+
/// Returns a function that schedules a runnable task when it gets woken up.
384+
fn schedule(&self) -> impl Fn(Runnable) + Send + Sync + 'static {
385+
let state = self.inner().state().clone();
386+
387+
move |runnable| {
388+
state.queue.push(runnable).unwrap();
389+
state.notify();
390+
}
391+
}
392+
378393
/// Returns a reference to the inner executor.
379-
fn inner(&self) -> &Executor<'a> {
394+
fn inner(&self) -> &Executor {
380395
self.inner.get_or_init(|| Executor::new())
381396
}
382397
}
383398

384-
impl<'a> Default for LocalExecutor<'a> {
385-
fn default() -> LocalExecutor<'a> {
399+
impl Default for LocalExecutor {
400+
fn default() -> LocalExecutor {
386401
LocalExecutor::new()
387402
}
388403
}
@@ -402,6 +417,7 @@ struct State {
402417
/// A list of sleeping tickers.
403418
sleepers: Mutex<Sleepers>,
404419

420+
/// Currently active tasks.
405421
active: Mutex<Arena<Waker>>,
406422
}
407423

0 commit comments

Comments
 (0)