Struct SharedDirectory

Source
pub struct SharedDirectory { /* private fields */ }
Expand description

This struct implements an “advisory lock” of a directory by using an auxiliary lock file to control the shared read access to it.

Internally, it uses the crate fd-lock to control the access to the lock file while protecting the access tot the actual file.

§Locking the same file in multiple threads

It is very important to notice that this struct is not thread safe and must be protected by a Mutex whenever necessary. It happens because the file offset pointer cannot be safely shared among multiple threads even for read operations. Unfortunately, the use of the mutex or other sync mechanisms will lead to the serialization of both read and write locks inside the same application.

Because of that, it is recommended to create multiple instances of this struct pointing to the same file. The access control will be guaranteed by the use of the lock file instead of the traditional thread sync mechanisms.

Implementations§

Source§

impl SharedDirectory

Source

pub const DEFAULT_LOCK_FILE_NAME: &'static str = ".~yonAOEyQtQXj90nWCzHYJA.lock"

This constant defines the default name of the file used to control the access to the directory.

This name was choosen to be as unlikely as possible in order to avoid accidental collisions with existing files. Following the nothing-up-my-sleeve number principle, the name of this file is actually the MD5 of the string “SharedDirectory lock file!” encoded in Base64 as defined by RFC 4648.

This claim can be checked with the command:

  • printf "SharedDirectory lock file!" | openssl md5 -binary | base64

While MD5 is no longer safe to be used as a cryptographic hash function, it can be used as a good way to hash values for other purposes.

Note from the author: I tried other variants of the above string but they where discarded because the end result were not suitable to be proper file names.

Source

pub fn new(directory: &Path) -> Result<Self>

Creates a new SharedDirectory. It will create a file inside the protected directory with the name defined by Self::DEFAULT_LOCK_FILE_NAME to control the access to it.

The protected directory will be automatically created it it does not exist.

Arguments:

  • directory: The directory to be protected;

Returns the new instance of an IO error to indicate what went wrong.

Source

pub fn with_lock_file_name( directory: &Path, lock_file_name: &str, ) -> Result<Self>

Creates a new SharedDirectory.

The protected directory will be automatically created it it does not exist.

Arguments:

  • directory: The directory to be protected;
  • lock_file_name: The lock file name. This file will be created inside the shared directory;

Returns the new instance of an IO error to indicate what went wrong.

Source

pub fn with_lock_file_path( directory: &Path, lock_file: &Path, recursive: bool, ) -> Result<Self>

Creates a new SharedDirectory.

The protected directory will be automatically created it it does not exist.

Arguments:

  • directory: The directory to be protected;
  • lock_file: The file to be used as the lock. This file will be created if it does not exist;
  • recursive: Create the full directory path recursively;

Returns the new instance of an IO error to indicate what went wrong.

Source

pub fn directory(&self) -> &Path

Returns the path to the protected directory.

Source

pub fn read(&mut self) -> Result<SharedDirectoryReadLockGuard<'_>>

Locks the file for shared read.

Returns read lock that grants access to the file.

Source

pub fn write(&mut self) -> Result<SharedDirectoryWriteLockGuard<'_>>

Locks the file for exclusive write and read

Returns read/write lock that grants access to the file.

Source

pub fn try_read(&mut self) -> Result<SharedDirectoryReadLockGuard<'_>>

Attempts to locks the file for shared read. It fails without waiting if the lock cannot be acquired.

Returns read lock that grants access to the file.

Source

pub fn try_write(&mut self) -> Result<SharedDirectoryWriteLockGuard<'_>>

Attempts to acquire the file lock for exclusive write and read. It fails without waiting if the lock cannot be acquired.

Returns read/write lock that grants access to the file.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V