From 717fc6ec8f02d741a3e1932628d91cbb7b25ae94 Mon Sep 17 00:00:00 2001 From: Adam Spofford Date: Thu, 18 Jan 2024 12:55:42 -0800 Subject: [PATCH 1/2] Add `is_recovering_from_trap` --- src/ic-cdk/src/api/call.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/ic-cdk/src/api/call.rs b/src/ic-cdk/src/api/call.rs index c43a30d2e..a58ca7daa 100644 --- a/src/ic-cdk/src/api/call.rs +++ b/src/ic-cdk/src/api/call.rs @@ -741,3 +741,19 @@ where Err(S::Error::custom("`Empty` cannot be serialized")) } } + +/// Tells you whether the current async fn is being canceled due to a trap/panic. +/// +/// If a function traps/panics, then the canister state is rewound to the beginning of the function. +/// However, due to the way async works, the beginning of the function as the IC understands it is actually +/// the most recent `await` from an inter-canister-call. This means that part of the function will have executed, +/// and part of it won't. +/// +/// When this happens the CDK will cancel the task, causing destructors to be run. If you need any functions to be run +/// no matter what happens, they should happen in a destructor; the [`scopeguard`](https://docs.rs/scopeguard) crate +/// provides a convenient wrapper for this. In a destructor, `is_recovering_from_trap` serves the same purpose as +/// [`is_panicking`](std::thread::is_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) +} From 6a401c1b6032475673cb6c93427e3be61415027f Mon Sep 17 00:00:00 2001 From: Adam Spofford Date: Thu, 18 Jan 2024 12:56:33 -0800 Subject: [PATCH 2/2] Changelog --- src/ic-cdk/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ic-cdk/CHANGELOG.md b/src/ic-cdk/CHANGELOG.md index d1f4b6954..6c7416b1c 100644 --- a/src/ic-cdk/CHANGELOG.md +++ b/src/ic-cdk/CHANGELOG.md @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [unreleased] +### Added + +- Add `is_recovering_from_trap` function for implementing trap cleanup logic + ## [0.12.1] - 2024-01-12 ### Changed