Skip to content

Commit b3d3d15

Browse files
committed
Improve lock API
1 parent af2f25c commit b3d3d15

1 file changed

Lines changed: 26 additions & 13 deletions

File tree

src/lib.rs

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ use std::{
167167
env, io,
168168
path::{Path, PathBuf},
169169
process::{Child, Command, ExitStatus},
170-
sync::{Arc, Mutex, mpsc},
170+
sync::{Arc, Mutex, MutexGuard, PoisonError, mpsc},
171171
thread,
172172
time::{Duration, Instant},
173173
};
@@ -306,19 +306,11 @@ impl Watch {
306306
/// This can be used as a binary semaphore between two execution paths that must not overlap.
307307
///
308308
/// Workspace's `target` directory and hidden paths are excluded by default.
309-
pub fn run_with_lock(
310-
self,
311-
commands: impl Into<CommandList>,
312-
lock: Arc<Mutex<()>>,
313-
) -> Result<()> {
309+
pub fn run_with_lock(self, commands: impl Into<CommandList>, lock: Lock) -> Result<()> {
314310
self.run_inner(commands, Some(lock))
315311
}
316312

317-
fn run_inner(
318-
mut self,
319-
commands: impl Into<CommandList>,
320-
lock: Option<Arc<Mutex<()>>>,
321-
) -> Result<()> {
313+
fn run_inner(mut self, commands: impl Into<CommandList>, lock: Option<Lock>) -> Result<()> {
322314
let metadata = metadata();
323315
let list = commands.into();
324316

@@ -384,7 +376,7 @@ impl Watch {
384376
log::info!("Re-running command");
385377
let mut current_child = current_child.clone();
386378
let mut list = list.clone();
387-
let lock = lock.as_ref().map(Arc::clone);
379+
let lock = lock.clone();
388380
thread::spawn(move || {
389381
let mut status = ExitStatus::default();
390382
let mut run_batch = || {
@@ -403,7 +395,7 @@ impl Watch {
403395
};
404396

405397
if let Some(lock) = lock {
406-
let _guard = lock.lock().expect("not poisoned");
398+
let _guard = lock.lock();
407399
run_batch();
408400
} else {
409401
run_batch();
@@ -707,6 +699,27 @@ impl CommandList {
707699
}
708700
}
709701

702+
/// A synchronization primitive shared between watch-driven command execution and
703+
/// external code that must not run concurrently.
704+
///
705+
/// Clone this type to share the same lock across threads/components.
706+
#[derive(Clone, Debug, Default)]
707+
pub struct Lock(Arc<Mutex<()>>);
708+
709+
impl Lock {
710+
/// Create a new lock instance.
711+
pub fn new() -> Self {
712+
Self::default()
713+
}
714+
715+
/// Acquire the lock, blocking the current thread until it is available.
716+
///
717+
/// The lock is released when the returned guard is dropped.
718+
pub fn lock(&self) -> Result<MutexGuard<'_, ()>, PoisonError<MutexGuard<'_, ()>>> {
719+
self.0.lock()
720+
}
721+
}
722+
710723
#[cfg(test)]
711724
mod test {
712725
use super::*;

0 commit comments

Comments
 (0)