Struct LockFile

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

A handle to a file that is lockable. Does not delete the file. On both Unix and Windows, the lock is held by an individual handle, and not by the whole process. On Unix, however, under fork file descriptors might be duplicated sharing the same lock, but fork is usually unsafe in Rust.

§Example

use fslock::LockFile;

let mut file = LockFile::open("testfiles/mylock.lock")?;
file.lock()?;
do_stuff();
file.unlock()?;

Implementations§

Source§

impl LockFile

Source

pub fn open<P>(path: &P) -> Result<Self, Error>
where P: ToOsStr + ?Sized,

Opens a file for locking, with OS-dependent locking behavior. On Unix, if the path is nul-terminated (ends with 0), no extra allocation will be made.

§Compatibility

This crate used to behave differently in regards to Unix and Windows, when locks on Unix were per-process and not per-handle. However, the current version locks per-handle on any platform. On Unix, however, under fork file descriptors might be duplicated sharing the same lock, but fork is usually unsafe in Rust.

§Panics

Panics if the path contains a nul-byte in a place other than the end.

§Example
use fslock::LockFile;

let mut file = LockFile::open("testfiles/regular.lock")?;
§Panicking Example
use fslock::LockFile;

let mut file = LockFile::open("my\0lock")?;
Examples found in repository?
examples/locks_until_nl.rs (line 18)
7fn main() -> Result<(), fslock::Error> {
8    let mut args = env::args();
9    args.next();
10
11    let path = match args.next() {
12        Some(arg) if args.next().is_none() => arg,
13        _ => {
14            eprintln!("Expected one argument");
15            process::exit(1);
16        },
17    };
18    let mut lockfile = LockFile::open(&path)?;
19    lockfile.lock()?;
20    io::stdin().read(&mut [0; 1])?;
21
22    Ok(())
23}
More examples
Hide additional examples
examples/try_lock.rs (line 19)
7fn main() -> Result<(), fslock::Error> {
8    let mut args = env::args();
9    args.next();
10
11    let path = match args.next() {
12        Some(arg) if args.next().is_none() => arg,
13        _ => {
14            eprintln!("Expected one argument");
15            process::exit(1);
16        },
17    };
18
19    let mut lockfile = LockFile::open(&path)?;
20
21    if lockfile.try_lock()? {
22        println!("SUCCESS");
23    } else {
24        println!("FAILURE");
25    }
26
27    Ok(())
28}
examples/try_lock_with_pid.rs (line 19)
7fn main() -> Result<(), fslock::Error> {
8    let mut args = env::args();
9    args.next();
10
11    let path = match args.next() {
12        Some(arg) if args.next().is_none() => arg,
13        _ => {
14            eprintln!("Expected one argument");
15            process::exit(1);
16        },
17    };
18
19    let mut lockfile = LockFile::open(&path)?;
20
21    if lockfile.try_lock_with_pid()? {
22        let content_a = read_to_string(&path)?;
23        let content_b = read_to_string(&path)?;
24        assert!(content_a.trim().len() > 0);
25        assert!(content_a.trim().chars().all(|ch| ch.is_ascii_digit()));
26        assert_eq!(content_a, content_b);
27
28        println!("{}", content_a);
29    } else {
30        println!("FAILURE");
31    }
32
33    Ok(())
34}
Source

pub fn lock(&mut self) -> Result<(), Error>

Locks this file. Blocks while it is not possible to lock (i.e. someone else already owns a lock). After locked, if no attempt to unlock is made, it will be automatically unlocked on the file handle drop.

§Panics

Panics if this handle already owns the file.

§Example
use fslock::LockFile;

let mut file = LockFile::open("testfiles/target.lock")?;
file.lock()?;
do_stuff();
file.unlock()?;
§Panicking Example
use fslock::LockFile;

let mut file = LockFile::open("testfiles/panicking.lock")?;
file.lock()?;
file.lock()?;
Examples found in repository?
examples/locks_until_nl.rs (line 19)
7fn main() -> Result<(), fslock::Error> {
8    let mut args = env::args();
9    args.next();
10
11    let path = match args.next() {
12        Some(arg) if args.next().is_none() => arg,
13        _ => {
14            eprintln!("Expected one argument");
15            process::exit(1);
16        },
17    };
18    let mut lockfile = LockFile::open(&path)?;
19    lockfile.lock()?;
20    io::stdin().read(&mut [0; 1])?;
21
22    Ok(())
23}
Source

pub fn lock_with_pid(&mut self) -> Result<(), Error>

Locks this file and writes this process’s PID into the file, which will be erased on unlock. Like LockFile::lock, blocks while it is not possible to lock. After locked, if no attempt to unlock is made, it will be automatically unlocked on the file handle drop.

§Panics

Panics if this handle already owns the file.

§Example
use fslock::LockFile;
use std::fs::read_to_string;

let mut file = LockFile::open("testfiles/withpid.lock")?;
file.lock_with_pid()?;
do_stuff()?;
file.unlock()?;

fn do_stuff() -> Result<(), fslock::Error> {
    let mut content = read_to_string("testfiles/withpid.lock")?;
    assert!(content.trim().len() > 0);
    assert!(content.trim().chars().all(|ch| ch.is_ascii_digit()));
    Ok(())
}
Source

pub fn try_lock(&mut self) -> Result<bool, Error>

Locks this file. Does NOT block if it is not possible to lock (i.e. someone else already owns a lock). After locked, if no attempt to unlock is made, it will be automatically unlocked on the file handle drop.

§Panics

Panics if this handle already owns the file.

§Example
use fslock::LockFile;

let mut file = LockFile::open("testfiles/attempt.lock")?;
if file.try_lock()? {
    do_stuff();
    file.unlock()?;
}
§Panicking Example
use fslock::LockFile;

let mut file = LockFile::open("testfiles/attempt_panic.lock")?;
file.lock()?;
file.try_lock()?;
Examples found in repository?
examples/try_lock.rs (line 21)
7fn main() -> Result<(), fslock::Error> {
8    let mut args = env::args();
9    args.next();
10
11    let path = match args.next() {
12        Some(arg) if args.next().is_none() => arg,
13        _ => {
14            eprintln!("Expected one argument");
15            process::exit(1);
16        },
17    };
18
19    let mut lockfile = LockFile::open(&path)?;
20
21    if lockfile.try_lock()? {
22        println!("SUCCESS");
23    } else {
24        println!("FAILURE");
25    }
26
27    Ok(())
28}
Source

pub fn try_lock_with_pid(&mut self) -> Result<bool, Error>

Locks this file and writes this process’s PID into the file, which will be erased on unlock. Does NOT block if it is not possible to lock (i.e. someone else already owns a lock). After locked, if no attempt to unlock is made, it will be automatically unlocked on the file handle drop.

§Panics

Panics if this handle already owns the file.

§Example
use fslock::LockFile;

let mut file = LockFile::open("testfiles/pid_attempt.lock")?;
if file.try_lock_with_pid()? {
    do_stuff()?;
    file.unlock()?;
}

fn do_stuff() -> Result<(), fslock::Error> {
    let mut content = read_to_string("testfiles/pid_attempt.lock")?;
    assert!(content.trim().len() > 0);
    assert!(content.trim().chars().all(|ch| ch.is_ascii_digit()));
    Ok(())
}
§Panicking Example
use fslock::LockFile;

let mut file = LockFile::open("testfiles/pid_attempt_panic.lock")?;
file.lock_with_pid()?;
file.try_lock_with_pid()?;
Examples found in repository?
examples/try_lock_with_pid.rs (line 21)
7fn main() -> Result<(), fslock::Error> {
8    let mut args = env::args();
9    args.next();
10
11    let path = match args.next() {
12        Some(arg) if args.next().is_none() => arg,
13        _ => {
14            eprintln!("Expected one argument");
15            process::exit(1);
16        },
17    };
18
19    let mut lockfile = LockFile::open(&path)?;
20
21    if lockfile.try_lock_with_pid()? {
22        let content_a = read_to_string(&path)?;
23        let content_b = read_to_string(&path)?;
24        assert!(content_a.trim().len() > 0);
25        assert!(content_a.trim().chars().all(|ch| ch.is_ascii_digit()));
26        assert_eq!(content_a, content_b);
27
28        println!("{}", content_a);
29    } else {
30        println!("FAILURE");
31    }
32
33    Ok(())
34}
Source

pub fn owns_lock(&self) -> bool

Returns whether this file handle owns the lock.

§Example
use fslock::LockFile;

let mut file = LockFile::open("testfiles/maybeowned.lock")?;
do_stuff_with_lock(&mut file);
if !file.owns_lock() {
    file.lock()?;
    do_stuff();
    file.unlock()?;
}
Source

pub fn unlock(&mut self) -> Result<(), Error>

Unlocks this file. This file handle must own the file lock. If not called manually, it is automatically called on drop.

§Panics

Panics if this handle does not own the file.

§Example
use fslock::LockFile;

let mut file = LockFile::open("testfiles/endinglock.lock")?;
file.lock()?;
do_stuff();
file.unlock()?;
§Panicking Example
use fslock::LockFile;

let mut file = LockFile::open("testfiles/endinglock.lock")?;
file.unlock()?;

Trait Implementations§

Source§

impl Debug for LockFile

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Drop for LockFile

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more

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.