Skip to content

Commit

Permalink
Different locking mecanism.
Browse files Browse the repository at this point in the history
  • Loading branch information
Narsil committed Jan 7, 2025
1 parent c9a4311 commit f9f6a05
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 24 deletions.
7 changes: 3 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ ureq = { version = "2.8.0", optional = true, features = [
"socks-proxy",
] }
native-tls = { version = "0.2.12", optional = true }
fs4 = { version = "0.12.0", default-features = false, optional = true }
libc = { version = "0.2", optional = true }

[features]
default = ["default-tls", "tokio", "ureq"]
Expand All @@ -60,7 +60,7 @@ tokio = [
"dep:thiserror",
"dep:tokio",
"tokio/rt-multi-thread",
"fs4/tokio",
"dep:libc",
]
ureq = [
"dep:http",
Expand All @@ -70,8 +70,7 @@ ureq = [
"dep:serde_json",
"dep:thiserror",
"dep:ureq",
"dep:fs4",
"fs4/sync",
"dep:libc",
]

[dev-dependencies]
Expand Down
29 changes: 16 additions & 13 deletions src/api/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use std::collections::HashMap;
use std::io::Read;
use std::io::Seek;
use std::num::ParseIntError;
use std::os::fd::AsRawFd;
use std::path::{Component, Path, PathBuf};
use std::str::FromStr;
use thiserror::Error;
Expand Down Expand Up @@ -72,29 +73,31 @@ impl HeaderAgent {
#[derive(Debug)]
struct Handle {
file: std::fs::File,
path: PathBuf,
}

impl Drop for Handle {
fn drop(&mut self) {
use fs4::fs_std::FileExt;
println!("Unlocking file {:?}", std::thread::current().id());
self.file.unlock().unwrap();
self.file.lock_exclusive().unwrap();
println!("Removing file {:?}", std::thread::current().id());
std::fs::remove_file(&self.path).ok();
self.file.unlock().unwrap();
println!("Final {:?}", std::thread::current().id());
unsafe { libc::flock(self.file.as_raw_fd(), libc::LOCK_UN) };
}
}

fn lock_file(mut path: PathBuf) -> Result<Handle, ApiError> {
use fs4::fs_std::FileExt;
path.set_extension("lock");

let file = std::fs::File::create(path.clone())?;
file.lock_exclusive()?;
println!("Acquired lock {:?}", std::thread::current().id());
Ok(Handle { path, file })
let mut res = unsafe { libc::flock(file.as_raw_fd(), libc::LOCK_EX | libc::LOCK_NB) };
for _ in 0..5 {
if res == 0 {
break;
}
std::thread::sleep(std::time::Duration::from_secs(1));
res = unsafe { libc::flock(file.as_raw_fd(), libc::LOCK_EX | libc::LOCK_NB) };
}
if res != 0 {
Err(ApiError::LockAcquisition(path))
} else {
Ok(Handle { file })
}
}

#[derive(Debug, Error)]
Expand Down
24 changes: 17 additions & 7 deletions src/api/tokio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use reqwest::{
use std::cmp::Reverse;
use std::collections::BinaryHeap;
use std::num::ParseIntError;
use std::os::fd::{AsFd, AsRawFd};
use std::path::{Component, Path, PathBuf};
use std::sync::Arc;
use thiserror::Error;
Expand Down Expand Up @@ -64,23 +65,32 @@ impl Progress for () {
}

struct Handle {
_file: tokio::fs::File,
path: PathBuf,
file: tokio::fs::File,
}

impl Drop for Handle {
fn drop(&mut self) {
std::fs::remove_file(&self.path).expect("Removing lockfile")
unsafe { libc::flock(self.file.as_fd().as_raw_fd(), libc::LOCK_UN) };
}
}

async fn lock_file(mut path: PathBuf) -> Result<Handle, ApiError> {
use fs4::tokio::AsyncFileExt;
path.set_extension("lock");

let file = tokio::fs::File::create(path.clone()).await?;
file.lock_exclusive()?;
let _file = file;
Ok(Handle { path, _file })
let mut res = unsafe { libc::flock(file.as_fd().as_raw_fd(), libc::LOCK_EX | libc::LOCK_NB) };
for _ in 0..5 {
if res == 0 {
break;
}
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
res = unsafe { libc::flock(file.as_fd().as_raw_fd(), libc::LOCK_EX | libc::LOCK_NB) };
}
if res != 0 {
Err(ApiError::LockAcquisition(path))
} else {
Ok(Handle { file })
}
}

#[derive(Debug, Error)]
Expand Down

0 comments on commit f9f6a05

Please sign in to comment.