pub struct CancelToken { /* private fields */ }Expand description
Cooperative cancellation handle for long-running MTP operations.
Cheap to clone (Arc-backed). Send + Sync. Once cancelled, the token
stays cancelled (no reset). Construct a fresh CancelToken per
logical operation.
A cheap-to-clone handle that callers pass into operations
like Storage::list_objects so they can
be aborted from another task. The operation checks the token between USB
roundtrips; when set, it returns Error::Cancelled
within one roundtrip’s worth of latency instead of running to completion.
§When to use this
MTP list and recursive delete on large folders consist of many small
per-object USB transactions (GetObjectInfo per handle). A 1k-photo
/DCIM/Camera listing on Android can take 15+ seconds over USB 2.0. Without
cooperative cancel, a user-initiated cancel only stops issuing new
transactions after the current bulk call’s entire for-loop completes. By
then the device may already be wedged from a follow-up op.
CancelToken gives every per-handle iteration a fast way to bail.
§Mid-data-phase cancel
For streaming downloads, see
FileDownload::cancel; that path uses
the USB Still Image Class (SIC) class-cancel mechanism to abort a long
bulk-IN transfer mid-stream. Per-handle list/delete operations don’t need
that: each GetObjectInfo / DeleteObject USB roundtrip completes in
milliseconds, so checking the token between roundtrips is sufficient and
safe (no half-finished transfer to drain).
§Example
use mtp_rs::{CancelToken, mtp::MtpDevice};
let device = MtpDevice::open_first().await?;
let storages = device.storages().await?;
let storage = &storages[0];
let cancel = CancelToken::new();
// Fire the cancel from another task after 500 ms.
let cancel_for_task = cancel.clone();
tokio::spawn(async move {
tokio::time::sleep(std::time::Duration::from_millis(500)).await;
cancel_for_task.cancel();
});
match storage.list_objects_with_cancel(None, Some(&cancel)).await {
Ok(objects) => println!("Listed {} objects", objects.len()),
Err(mtp_rs::Error::Cancelled) => println!("Cancelled mid-listing"),
Err(e) => return Err(e),
}Implementations§
Source§impl CancelToken
impl CancelToken
Sourcepub fn from_arc(cancelled: Arc<AtomicBool>) -> Self
pub fn from_arc(cancelled: Arc<AtomicBool>) -> Self
Wraps an externally-owned Arc<AtomicBool>.
Use this when the caller already has its own cancellation flag (for example, threaded through several layers from a host application) and wants the same atomic to drive an mtp-rs operation, with no second polling task. The token shares ownership of the inner atomic, so flipping the original flag flips the token (and vice versa).
Sourcepub fn cancel(&self)
pub fn cancel(&self)
Marks the token as cancelled. Subsequent is_cancelled calls return
true. Cooperative consumers (operations holding Option<&CancelToken>)
bail at their next check point with Err(Error::Cancelled).
Idempotent: calling on an already-cancelled token is a no-op.
Sourcepub fn is_cancelled(&self) -> bool
pub fn is_cancelled(&self) -> bool
Returns true once cancel has been called on this token (or any
clone of it).