Skip to content

Commit

Permalink
impl Drop for async File & Volume with embassy_futures::block_on
Browse files Browse the repository at this point in the history
  • Loading branch information
Be-ing committed Feb 12, 2025
1 parent e623266 commit 3c49859
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 9 deletions.
4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ rust-version = "1.76"
bisync = "0.3.0"
byteorder = {version = "1", default-features = false}
defmt = {version = "0.3", optional = true}
embassy-futures = {version = "0.1.1", optional = true}
embedded-hal = "1.0.0"
embedded-hal-async = "1.0.0"
embedded-io = "0.6.1"
Expand All @@ -33,6 +34,7 @@ hex-literal = "0.4.1"
sha2 = "0.10"

[features]
default = ["log"]
default = ["log", "async-drop"]
defmt-log = ["dep:defmt"]
log = ["dep:log"]
async-drop = ["dep:embassy-futures"]
23 changes: 19 additions & 4 deletions src/inner/filesystem/files.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::super::super::{bisync, only_sync};
use super::super::super::{bisync, only_sync, only_async};
use super::super::super::{ErrorType, Read, Seek, SeekFrom, Write};
use super::super::{
filesystem::{ClusterId, DirEntry, Handle},
Expand Down Expand Up @@ -49,8 +49,11 @@ impl RawFile {
/// error that may occur will be ignored. To handle potential errors, use
/// the [`File::close`] method.
///
/// For async Files, async drop does not exist in Rust, so you *must* call
/// [`File::close`] when you are done with a File.
/// For async Files, the implementation of [`Drop`] blocks with [`embassy_futures::block_on`]
/// because there is no way to `.await` inside [`Drop::drop`]. If you would prefer
/// to call [`File::close`] manually instead and rely on the async executor you are already
/// using, you can do that by disabling the `async-drop` Cargo feature, which is enabled by
/// default.
pub struct File<'a, D, T, const MAX_DIRS: usize, const MAX_FILES: usize, const MAX_VOLUMES: usize>
where
D: BlockDevice,
Expand Down Expand Up @@ -150,7 +153,6 @@ where
}
}

// async drop does not yet exist :(
#[only_sync]
impl<'a, D, T, const MAX_DIRS: usize, const MAX_FILES: usize, const MAX_VOLUMES: usize> Drop
for File<'a, D, T, MAX_DIRS, MAX_FILES, MAX_VOLUMES>
Expand All @@ -163,6 +165,19 @@ where
}
}

#[cfg(feature = "async-drop")]
#[only_async]
impl<'a, D, T, const MAX_DIRS: usize, const MAX_FILES: usize, const MAX_VOLUMES: usize> Drop
for File<'a, D, T, MAX_DIRS, MAX_FILES, MAX_VOLUMES>
where
D: BlockDevice,
T: TimeSource,
{
fn drop(&mut self) {
_ = embassy_futures::block_on(self.volume_mgr.close_file(self.raw_file));
}
}

impl<'a, D, T, const MAX_DIRS: usize, const MAX_FILES: usize, const MAX_VOLUMES: usize>
core::fmt::Debug for File<'a, D, T, MAX_DIRS, MAX_FILES, MAX_VOLUMES>
where
Expand Down
23 changes: 19 additions & 4 deletions src/inner/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use core::fmt::Debug;
use embedded_io::ErrorKind;
use filesystem::Handle;

use super::{bisync, only_sync};
use super::{bisync, only_sync, only_async};

#[doc(inline)]
pub use blockdevice::{Block, BlockCache, BlockCount, BlockDevice, BlockIdx};
Expand Down Expand Up @@ -210,8 +210,11 @@ impl RawVolume {
/// any error that may occur will be ignored. To handle potential errors, use
/// the [`Volume::close`] method.
///
/// For async Volumes, async drop does not exist in Rust, so you *must* call
/// [`Volume::close`] when you are done with a Volume.
/// For async Volumes, the implementation of [`Drop`] blocks with [`embassy_futures::block_on`]
/// because there is no way to `.await` inside [`Drop::drop`]. If you would prefer
/// to call [`File::close`] manually instead and rely on the async executor you are already
/// using, you can do that by disabling the `async-drop` Cargo feature, which is enabled by
/// default.
pub struct Volume<'a, D, T, const MAX_DIRS: usize, const MAX_FILES: usize, const MAX_VOLUMES: usize>
where
D: BlockDevice,
Expand Down Expand Up @@ -268,7 +271,6 @@ where
}
}

// async drop does not yet exist :(
#[only_sync]
impl<'a, D, T, const MAX_DIRS: usize, const MAX_FILES: usize, const MAX_VOLUMES: usize> Drop
for Volume<'a, D, T, MAX_DIRS, MAX_FILES, MAX_VOLUMES>
Expand All @@ -281,6 +283,19 @@ where
}
}

#[cfg(feature = "async-drop")]
#[only_async]
impl<'a, D, T, const MAX_DIRS: usize, const MAX_FILES: usize, const MAX_VOLUMES: usize> Drop
for Volume<'a, D, T, MAX_DIRS, MAX_FILES, MAX_VOLUMES>
where
D: BlockDevice,
T: TimeSource,
{
fn drop(&mut self) {
_ = embassy_futures::block_on(self.volume_mgr.close_volume(self.raw_volume));
}
}

impl<'a, D, T, const MAX_DIRS: usize, const MAX_FILES: usize, const MAX_VOLUMES: usize>
core::fmt::Debug for Volume<'a, D, T, MAX_DIRS, MAX_FILES, MAX_VOLUMES>
where
Expand Down
4 changes: 4 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@
//!
//! ## Features
//!
//! * `async-drop`: Enabled by default. Implements [`Drop`] for [`asynchronous::File`]
//! and [`asynchronous::Volume`] using [`embassy_futures::block_on`]. Disable if
//! you would prefer to call [`asynchronous::File::close`] and [`asynchronous::Volume::close`]
//! manually using the async executor you are already using.
//! * `log`: Enabled by default. Generates log messages using the `log` crate.
//! * `defmt-log`: By turning off the default features and enabling the
//! `defmt-log` feature you can configure this crate to log messages over defmt
Expand Down

0 comments on commit 3c49859

Please sign in to comment.