1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
macro_rules! async_file_ext {
($file: ty, $file_name: literal) => {
use std::io::Result;
#[doc = concat!("Extension trait for `", $file_name, "` which provides allocation, duplication and locking methods.")]
///
/// ## Notes on File Locks
///
/// This library provides whole-file locks in both shared (read) and exclusive
/// (read-write) varieties.
///
/// File locks are a cross-platform hazard since the file lock APIs exposed by
/// operating system kernels vary in subtle and not-so-subtle ways.
///
/// The API exposed by this library can be safely used across platforms as long
/// as the following rules are followed:
///
/// * Multiple locks should not be created on an individual `File` instance
/// concurrently.
/// * Duplicated files should not be locked without great care.
/// * Files to be locked should be opened with at least read or write
/// permissions.
/// * File locks may only be relied upon to be advisory.
///
/// See the tests in `lib.rs` for cross-platform lock behavior that may be
/// relied upon; see the tests in `unix.rs` and `windows.rs` for examples of
/// platform-specific behavior. File locks are implemented with
/// [`flock(2)`](http://man7.org/linux/man-pages/man2/flock.2.html) on Unix and
/// [`LockFile`](https://msdn.microsoft.com/en-us/library/windows/desktop/aa365202(v=vs.85).aspx)
/// on Windows.
#[async_trait::async_trait]
pub trait AsyncFileExt {
/// Returns the amount of physical space allocated for a file.
async fn allocated_size(&self) -> Result<u64>;
/// Ensures that at least `len` bytes of disk space are allocated for the
/// file, and the file size is at least `len` bytes. After a successful call
/// to `allocate`, subsequent writes to the file within the specified length
/// are guaranteed not to fail because of lack of disk space.
async fn allocate(&self, len: u64) -> Result<()>;
/// Locks the file for shared usage, blocking if the file is currently
/// locked exclusively.
fn lock_shared(&self) -> Result<()>;
/// Locks the file for exclusive usage, blocking if the file is currently
/// locked.
fn lock_exclusive(&self) -> Result<()>;
/// Locks the file for shared usage, or returns a an error if the file is
/// currently locked (see `lock_contended_error`).
fn try_lock_shared(&self) -> Result<()>;
/// Locks the file for shared usage, or returns a an error if the file is
/// currently locked (see `lock_contended_error`).
fn try_lock_exclusive(&self) -> Result<()>;
/// Unlocks the file.
fn unlock(&self) -> Result<()>;
}
#[async_trait::async_trait]
impl AsyncFileExt for $file {
async fn allocated_size(&self) -> Result<u64> {
sys::allocated_size(self).await
}
async fn allocate(&self, len: u64) -> Result<()> {
sys::allocate(self, len).await
}
fn lock_shared(&self) -> Result<()> {
sys::lock_shared(self)
}
fn lock_exclusive(&self) -> Result<()> {
sys::lock_exclusive(self)
}
fn try_lock_shared(&self) -> Result<()> {
sys::try_lock_shared(self)
}
fn try_lock_exclusive(&self) -> Result<()> {
sys::try_lock_exclusive(self)
}
fn unlock(&self) -> Result<()> {
sys::unlock(self)
}
}
}
}
cfg_async_std! {
pub(crate) mod async_std_impl;
}
cfg_smol! {
pub(crate) mod smol_impl;
}
cfg_tokio! {
pub(crate) mod tokio_impl;
}