#semaphore #lock #lock-file #ipc #file #mutex #locking

simplelock

Simple abstractions for inter-process synchronization

5 releases (3 breaking)

0.4.1 Nov 30, 2020
0.4.0 Jun 4, 2020
0.3.0 May 30, 2020
0.2.0 May 25, 2020
0.1.0 May 24, 2020

#803 in Concurrency

MIT license

38KB
553 lines

Simple Lock

Current Release: 0.4.1

License builds.sr.ht status Latest version Documentation

A simple locking abstraction for inter-process/thread synchronization in rust.

Features:

By default, no features will be enabled and only the Lock trait and utility functionality will be available. This can be useful if you wish to hand-roll your own Lock, but don't want to re-write the utility functions.

Current implementations:

  • fake - Enables the FakeLock implementation (only useful for testing).
  • file - Enables the FileLock implementation (most common and cross-platform).
  • sema - Enables the SemaphoreLock implementation (minimal, libc/nix only).

Examples:

A basic example

use simplelock::*;

// Our application's lock namespace. We use this on creation to allow for
// cross-process synchronization. This lets multiple instances of this
// application run at once without conflicting.
const MY_APP_NAME: &str = "my_app_name";

fn main() -> SimpleLockResult<()> {
    // Creates the lock based on the "feature" enabled in Cargo.toml.
    // Will return a SimpleLockError if an error happens when creating
    // the lock with the default configuration, or if no lock type was
    // enabled as a "feature".
    let mut lock = default_lock(MY_APP_NAME)?;

    // One of the utility functions provided, simple critical-section
    // locking. All of the bundled Locks' behaviours, will, by default,
    // hang until the lock is available. This can be customized.
    let result = lock_until_finished(
        &mut lock,
        || {
            /// Some critical code.
        })?;

    // ... Do something with the result.
}

If you needed more customization of a lock's behaviour, you may use the LockBuilder to override lock/unlock behaviour.

use simplelock::*;

fn main() -> SimpleLockResult<()> {
    let mut lock = LockBuilder::default()
                       .with_try_lock()      // Allow immediate return if lock taken.
                       .with_silent_unlock() // Suppress failure to return result.
                       .build(MY_APP_NAME)?;

    // do something with your lock.
}

If you wanted to implement your own lock, you can implement the Lock trait or ConcreteLock and use it with all the same utility functionality provided by this package. If you do not enable any features, this package is only the trait and utility functions.

Caveats:

If you are ok with the below, then go ahead and use this package.

  • unsafe - The "semaphore" lock implementation has unsafe code, this is because the nix package does not have implementations for POSIX semaphores yet. If this is unacceptable, don't enable the "semaphore" feature.
  • no_std - We currently do not have any non-stdlib available lock implementations ("semaphore" is close). Some utility functionality uses std but some rework before v1.0 is needed before then.

Contributing:

Please see doc/CONTRIBUTING.md.

FAQ:

Please see doc/FAQ.md.

Dependencies

~0.3–1.6MB
~33K SLoC