#raii #mutex #flock #file-lock

fmutex

Cross-platform mutual exclusion across processes on a file or path

4 releases (2 breaking)

0.3.0 May 22, 2025
0.2.1 Mar 10, 2025
0.2.0 Mar 8, 2025
0.1.0 Feb 9, 2022

#494 in Filesystem

Download history 582/week @ 2025-10-03 480/week @ 2025-10-10 676/week @ 2025-10-17 893/week @ 2025-10-24 406/week @ 2025-10-31 586/week @ 2025-11-07 748/week @ 2025-11-14 504/week @ 2025-11-21 408/week @ 2025-11-28 882/week @ 2025-12-05 814/week @ 2025-12-12 157/week @ 2025-12-19 88/week @ 2025-12-26 407/week @ 2026-01-02 177/week @ 2026-01-09 380/week @ 2026-01-16

1,063 downloads per month
Used in 3 crates

MIT/Apache

27KB
302 lines

fmutex

Crates.io Version Docs.rs Latest Build Status

Mutual exclusion across processes on a file descriptor or path.

  • On Unix-like systems this is implemented use flock(2).
  • On Windows this is implemented using LockFileEx.

🚀 Getting started

First add fmutex to your Cargo manifest.

cargo add fmutex

Now use one of the provided functions to lock a file descriptor (Unix) or handle (Windows) or a file path.

For exclusive locks (only one process can hold the lock):

For shared locks (multiple processes can hold the lock simultaneously, but not when an exclusive lock is held):

🤸 Usage

lock_exclusive()

let fd = fs::OpenOptions::new().create(true).write(true).open(&path)?;

{
    let _guard = fmutex::lock_exclusive(&fd)?;

    // do mutually exclusive stuff here

} // <-- `_guard` dropped here and the lock is released

try_lock_exclusive()

let fd = fs::OpenOptions::new().create(true).write(true).open(&path)?;

match fmutex::try_lock_exclusive(&fd)? {
    Some(_guard) => {

        // do mutually exclusive stuff here

    } // <-- `_guard` dropped here and the lock is released

    None => {
        eprintln!("the lock could not be acquired!");
    }
}

lock_exclusive_path()

let path = "path/to/my/file.txt";

{
    let _guard = fmutex::lock_exclusive_path(path)?;

    // do mutually exclusive stuff here

} // <-- `_guard` dropped here and the lock is released

try_lock_exclusive_path()

let path = "path/to/my/file.txt";

match fmutex::try_lock_exclusive_path(path)? {
    Some(_guard) => {

        // do mutually exclusive stuff here

    } // <-- `_guard` dropped here and the lock is released

    None => {
        eprintln!("the lock could not be acquired!");
    }
}

lock_shared()

let fd = fs::OpenOptions::new().create(true).write(true).open(&path)?;

{
    let _guard = fmutex::lock_shared(&fd)?;

    // do shared read-only operations here
    // other processes can also acquire shared locks simultaneously

} // <-- `_guard` dropped here and the lock is released

try_lock_shared()

let fd = fs::OpenOptions::new().create(true).write(true).open(&path)?;

match fmutex::try_lock_shared(&fd)? {
    Some(_guard) => {

        // do shared read-only operations here
        // other processes can also acquire shared locks simultaneously

    } // <-- `_guard` dropped here and the lock is released

    None => {
        eprintln!("the shared lock could not be acquired (file is exclusively locked)!");
    }
}

lock_shared_path()

let path = "path/to/my/file.txt";

{
    let _guard = fmutex::lock_shared_path(path)?;

    // do shared read-only operations here
    // other processes can also acquire shared locks simultaneously

} // <-- `_guard` dropped here and the lock is released

try_lock_shared_path()

let path = "path/to/my/file.txt";

match fmutex::try_lock_shared_path(path)? {
    Some(_guard) => {

        // do shared read-only operations here
        // other processes can also acquire shared locks simultaneously

    } // <-- `_guard` dropped here and the lock is released

    None => {
        eprintln!("the shared lock could not be acquired (file is exclusively locked)!");
    }
}

License

This project is distributed under the terms of both the MIT license and the Apache License (Version 2.0).

See LICENSE-APACHE and LICENSE-MIT for details.

Dependencies

~0–12MB
~81K SLoC