1 use std::fs::{File, OpenOptions};
4 use std::os::windows::prelude::*;
7 use winapi::shared::winerror::ERROR_INVALID_FUNCTION;
8 use winapi::um::fileapi::LockFileEx;
9 use winapi::um::minwinbase::{LOCKFILE_EXCLUSIVE_LOCK, LOCKFILE_FAIL_IMMEDIATELY, OVERLAPPED};
10 use winapi::um::winnt::{FILE_SHARE_DELETE, FILE_SHARE_READ, FILE_SHARE_WRITE};
18 pub fn new(p: &Path, wait: bool, create: bool, exclusive: bool) -> io::Result<Lock> {
20 p.parent().unwrap().exists(),
21 "Parent directory of lock-file must exist: {}",
25 let share_mode = FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE;
27 let mut open_options = OpenOptions::new();
28 open_options.read(true).share_mode(share_mode);
31 open_options.create(true).write(true);
34 debug!("attempting to open lock file `{}`", p.display());
35 let file = match open_options.open(p) {
37 debug!("lock file opened successfully");
41 debug!("error opening lock file: {}", err);
47 let mut overlapped: OVERLAPPED = mem::zeroed();
51 dwFlags |= LOCKFILE_FAIL_IMMEDIATELY;
55 dwFlags |= LOCKFILE_EXCLUSIVE_LOCK;
58 debug!("attempting to acquire lock on lock file `{}`", p.display());
59 LockFileEx(file.as_raw_handle(), dwFlags, 0, 0xFFFF_FFFF, 0xFFFF_FFFF, &mut overlapped)
62 let err = io::Error::last_os_error();
63 debug!("failed acquiring file lock: {}", err);
66 debug!("successfully acquired lock");
67 Ok(Lock { _file: file })
71 pub fn error_unsupported(err: &io::Error) -> bool {
72 err.raw_os_error() == Some(ERROR_INVALID_FUNCTION as i32)
76 // Note that we don't need a Drop impl on Windows: The file is unlocked
77 // automatically when it's closed.