Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ opt-level = 'z'
[workspace.dependencies]
ic0 = { path = "src/ic0", version = "0.23.0" }
ic-cdk = { path = "src/ic-cdk", version = "0.17.1" }
ic-cdk-executor = { path = "src/ic-cdk-executor", version = "0.1.0" }
ic-cdk-timers = { path = "src/ic-cdk-timers", version = "0.11.0" }

candid = "0.10.4"
Expand Down
16 changes: 16 additions & 0 deletions src/ic-cdk-executor/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]
name = "ic-cdk-executor"
version = "0.1.0"
authors.workspace = true
edition.workspace = true
repository.workspace = true
rust-version.workspace = true
license.workspace = true
description = "Async executor for `ic-cdk`"
categories = ["asynchronous", "rust-patterns"]
keywords = ["internet-computer", "dfinity", "canister", "cdk"]
# DO NOT change this field, not even to update the link, unless you are updating every existing version of the package.
# Update the link by updating the links-pin tag.
links = "ic-cdk async executor, see https://github.com/dfinity/cdk-rs/blob/links-pin/TROUBLESHOOTING.md"

[dependencies]
3 changes: 3 additions & 0 deletions src/ic-cdk-executor/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn main() {
// dummy build script, required by `package.links`
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! An async executor for [`ic-cdk`](https://docs.rs/ic-cdk). Most users should not use this crate directly.

use std::cell::{Cell, RefCell};
use std::future::Future;
use std::pin::Pin;
Expand Down Expand Up @@ -26,7 +28,9 @@ pub fn spawn<F: 'static + Future<Output = ()>>(future: F) {
.poll(&mut Context::from_waker(&waker));
}

pub(crate) static CLEANUP: AtomicBool = AtomicBool::new(false);
/// In a cleanup callback, this is set to `true` before calling `wake`, and `false` afterwards.
/// This ensures that `wake` will not actually run the future, but instead cancel it and run its destructor.
pub static CLEANUP: AtomicBool = AtomicBool::new(false);

// This module contains the implementation of a waker we're using for waking
// top-level futures (the ones returned by canister methods). Rc handles the
Expand Down Expand Up @@ -88,7 +92,7 @@ mod waker {
if super::CLEANUP.load(Ordering::Relaxed) {
state.previous_trap.set(true);
} else if state.previous_trap.get() {
crate::trap("Call already trapped");
panic!("Call already trapped");
} else {
let waker = waker(Rc::clone(&state));
let Ok(mut borrow) = state.future.try_borrow_mut() else {
Expand Down
1 change: 1 addition & 0 deletions src/ic-cdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ include = ["src", "Cargo.toml", "LICENSE", "README.md"]
[dependencies]
candid.workspace = true
ic0.workspace = true
ic-cdk-executor.workspace = true
# Pin ic-cdk-macros to a specific version.
# This actually create a 1-to-1 mapping between ic-cdk and ic-cdk-macros.
# Dependents won't accidentaly upgrading ic-cdk-macros only but not ic-cdk.
Expand Down
6 changes: 3 additions & 3 deletions src/ic-cdk/src/api/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,9 +182,9 @@ unsafe extern "C" fn cleanup<T: AsRef<[u8]>>(state_ptr: *const RwLock<CallFuture
if let Some(waker) = w {
// Flag that we do not want to actually wake the task - we
// want to drop it *without* executing it.
crate::futures::CLEANUP.store(true, Ordering::Relaxed);
ic_cdk_executor::CLEANUP.store(true, Ordering::Relaxed);
waker.wake();
crate::futures::CLEANUP.store(false, Ordering::Relaxed);
ic_cdk_executor::CLEANUP.store(false, Ordering::Relaxed);
}
}
}
Expand Down Expand Up @@ -873,5 +873,5 @@ where
/// [std::thread::panicking] - it tells you whether the destructor is executing *because* of a trap,
/// as opposed to just because the scope was exited, so you could e.g. implement mutex poisoning.
pub fn is_recovering_from_trap() -> bool {
crate::futures::CLEANUP.load(Ordering::Relaxed)
ic_cdk_executor::CLEANUP.load(Ordering::Relaxed)
}
5 changes: 2 additions & 3 deletions src/ic-cdk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
compile_error!("This version of the CDK does not support multithreading.");

pub mod api;
mod futures;
mod macros;
mod printer;
pub mod storage;
Expand Down Expand Up @@ -45,13 +44,13 @@ pub fn setup() {
note = "Use the spawn() function instead, it does the same thing but is more appropriately named."
)]
pub fn block_on<F: 'static + std::future::Future<Output = ()>>(future: F) {
futures::spawn(future);
ic_cdk_executor::spawn(future);
}

/// Spawn an asynchronous task that drives the provided future to
/// completion.
pub fn spawn<F: 'static + std::future::Future<Output = ()>>(future: F) {
futures::spawn(future);
ic_cdk_executor::spawn(future);
}

/// Format and then print the formatted message
Expand Down