API Reference
Complete API documentation for File-Based Semaphore.
Types
Semaphore
Main semaphore struct for coordinating access.
pub struct Semaphore {
path: PathBuf,
config: SemaphoreConfig,
}SemaphoreConfig
Configuration for semaphore behavior.
pub struct SemaphoreConfig {
/// Stale lock timeout. Locks older than this are auto-cleaned.
/// Default: Some(Duration::from_secs(3600))
pub stale_timeout: Option<Duration>,
/// Maximum time to wait when acquiring.
/// Default: None (wait forever)
pub acquire_timeout: Option<Duration>,
/// Interval between acquisition retries.
/// Default: Duration::from_millis(100)
pub retry_interval: Duration,
}SemaphoreGuard
RAII guard that releases the lock when dropped.
pub struct SemaphoreGuard<'a> {
semaphore: &'a Semaphore,
}LockInfo
Information about a lock holder.
pub struct LockInfo {
/// Process ID of lock holder
pub pid: u32,
/// Unix timestamp when lock was acquired
pub timestamp: u64,
/// Optional description/tag
pub tag: Option<String>,
}SemaphoreError
Error types for semaphore operations.
pub enum SemaphoreError {
/// Lock already held by another process
AlreadyLocked {
holder_pid: Option<u32>,
locked_since: Option<u64>,
},
/// Lock file path is invalid
InvalidPath(String),
/// IO error during lock operations
IoError(std::io::Error),
/// Lock was not held when trying to release
NotLocked,
/// Timeout waiting for lock
Timeout,
/// Failed to parse lock file contents
ParseError(String),
}Semaphore Methods
new
Create a new semaphore with configuration.
pub fn new(path: impl AsRef<Path>, config: SemaphoreConfig) -> Result<Self, SemaphoreError>Parameters:
path- Path to the lock fileconfig- Configuration options
Returns: Result<Semaphore, SemaphoreError>
Errors:
InvalidPath- Path is empty or parent directory doesn't exist
with_defaults
Create a semaphore with default configuration.
pub fn with_defaults(path: impl AsRef<Path>) -> Result<Self, SemaphoreError>try_acquire
Non-blocking lock acquisition.
pub fn try_acquire(&self) -> Result<SemaphoreGuard<'_>, SemaphoreError>Returns: Result<SemaphoreGuard, SemaphoreError>
Errors:
AlreadyLocked- Lock is held by another processIoError- Filesystem error
try_acquire_with_info
Non-blocking acquisition with custom lock info.
pub fn try_acquire_with_info(&self, info: LockInfo) -> Result<SemaphoreGuard<'_>, SemaphoreError>acquire
Blocking lock acquisition (uses config timeout).
pub fn acquire(&self) -> Result<SemaphoreGuard<'_>, SemaphoreError>Errors:
Timeout- Timed out waiting for lockIoError- Filesystem error
acquire_with_info
Blocking acquisition with custom lock info.
pub fn acquire_with_info(&self, info: LockInfo) -> Result<SemaphoreGuard<'_>, SemaphoreError>acquire_timeout
Blocking acquisition with specific timeout.
pub fn acquire_timeout(&self, timeout: Duration) -> Result<SemaphoreGuard<'_>, SemaphoreError>is_locked
Check if the lock is currently held.
pub fn is_locked(&self) -> boollock_info
Get information about the current lock holder.
pub fn lock_info(&self) -> Option<LockInfo>Returns: Some(LockInfo) if locked, None if free
force_release
Force release a lock (even if held by another process).
pub fn force_release(&self) -> Result<(), SemaphoreError>Warning: Use with caution - can break coordination.
path
Get the path to the lock file.
pub fn path(&self) -> &Pathis_process_running
Check if a process is still running (Unix only).
#[cfg(unix)]
pub fn is_process_running(pid: u32) -> boolLockInfo Methods
new
Create lock info for current process.
pub fn new() -> Selfwith_tag
Create lock info with a custom tag.
pub fn with_tag(tag: impl Into<String>) -> Selfserialize
Serialize to lock file format.
pub fn serialize(&self) -> Stringparse
Parse from lock file contents.
pub fn parse(content: &str) -> Result<Self, SemaphoreError>is_stale
Check if lock is stale based on timeout.
pub fn is_stale(&self, timeout: Duration) -> boolSemaphoreConfig Default
impl Default for SemaphoreConfig {
fn default() -> Self {
Self {
stale_timeout: Some(Duration::from_secs(3600)),
acquire_timeout: None,
retry_interval: Duration::from_millis(100),
}
}
}Error Display
All errors implement Display and Error:
use file_based_semaphore::SemaphoreError;
let err = SemaphoreError::Timeout;
println!("{}", err); // "Timeout waiting for lock"
let err = SemaphoreError::AlreadyLocked {
holder_pid: Some(12345),
locked_since: Some(1703520000),
};
println!("{}", err); // "Lock already held by PID 12345 since 1703520000"Thread Safety
SemaphoreisSend + SyncSemaphoreGuardisSendbut notSync- Multiple threads can share a
SemaphoreviaArc
Example: Complete Usage
use file_based_semaphore::{Semaphore, SemaphoreConfig, LockInfo, SemaphoreError};
use std::time::Duration;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Configure
let config = SemaphoreConfig {
stale_timeout: Some(Duration::from_secs(300)),
acquire_timeout: Some(Duration::from_secs(30)),
retry_interval: Duration::from_millis(50),
};
// Create
let sem = Semaphore::new("/tmp/example.lock", config)?;
// Check status
println!("Locked: {}", sem.is_locked());
// Acquire with tag
let info = LockInfo::with_tag("example-operation");
match sem.acquire_with_info(info) {
Ok(guard) => {
println!("Lock acquired!");
// Read lock info
if let Some(info) = sem.lock_info() {
println!("Held by PID: {}", info.pid);
}
// Work...
drop(guard); // Explicit release (or let it drop)
}
Err(SemaphoreError::Timeout) => {
println!("Timed out");
}
Err(e) => {
return Err(e.into());
}
}
Ok(())
}