Mercurial > lbo > hg > leveldb-rs
changeset 526:79e0bbc4f604
replace libc usage with fs2, support windows
author | João Oliveira <hello@jxs.pt> |
---|---|
date | Mon, 18 May 2020 23:43:14 +0100 |
parents | c0e92d14e550 |
children | deb79bf7f240 |
files | Cargo.toml src/disk_env.rs src/env.rs src/lib.rs src/version_set.rs |
diffstat | 5 files changed, 30 insertions(+), 39 deletions(-) [+] |
line wrap: on
line diff
--- a/Cargo.toml Tue Mar 24 07:09:47 2020 +0100 +++ b/Cargo.toml Mon May 18 23:43:14 2020 +0100 @@ -13,10 +13,10 @@ [dependencies] crc = "1.8" integer-encoding = "1.0" -libc = "0.2" rand = "0.7" snap = "1.0" errno = "0.2" +fs2 = "0.4.3" [dev-dependencies] time-test = "0.2"
--- a/src/disk_env.rs Tue Mar 24 07:09:47 2020 +0100 +++ b/src/disk_env.rs Mon May 18 23:43:14 2020 +0100 @@ -1,26 +1,20 @@ use env::{path_to_str, Env, FileLock, Logger, RandomAccess}; use env_common::{micros, sleep_for}; use error::{err, Result, Status, StatusCode}; +use fs2::FileExt; use std::collections::HashMap; -use std::fs; -use std::io::{self, Read, Write}; +use std::fs::{self, File}; +use std::io::{self, Read, Write, ErrorKind}; use std::iter::FromIterator; -use std::os::unix::io::IntoRawFd; use std::path::{Path, PathBuf}; use std::sync::{Arc, Mutex}; -use libc; - -const F_RDLCK: libc::c_short = 0; -const F_WRLCK: libc::c_short = 1; -const F_UNLCK: libc::c_short = 2; - type FileDescriptor = i32; #[derive(Clone)] pub struct PosixDiskEnv { - locks: Arc<Mutex<HashMap<String, FileDescriptor>>>, + locks: Arc<Mutex<HashMap<String, File>>>, } impl PosixDiskEnv { @@ -127,23 +121,19 @@ .open(p) .map_err(|e| map_err_with_name("lock", p, e))?; - let fd = f.into_raw_fd(); - let result = unsafe { libc::flock(fd as libc::c_int, libc::LOCK_EX | libc::LOCK_NB) }; - - if result < 0 { - if errno::errno() == errno::Errno(libc::EWOULDBLOCK) { - return Err(Status::new( + match f.try_lock_exclusive() { + Err(err) if err.kind() == ErrorKind::WouldBlock => return Err(Status::new( StatusCode::LockError, "lock on database is already held by different process", - )); - } - return Err(Status::new( + )), + Err(_) => return Err(Status::new( StatusCode::Errno(errno::errno()), - &format!("unknown lock error on fd {} (file {})", fd, p.display()), - )); - } + &format!("unknown lock error on file {:?} (file {})", f, p.display()), + )), + _ => (), + }; - locks.insert(p.to_str().unwrap().to_string(), fd); + locks.insert(p.to_str().unwrap().to_string(), f); let lock = FileLock { id: p.to_str().unwrap().to_string(), }; @@ -158,16 +148,8 @@ &format!("unlocking a file that is not locked: {}", l.id), ); } else { - let fd = locks.remove(&l.id).unwrap(); - let result = unsafe { - let ok = libc::fcntl(fd, libc::F_GETFD); - if ok < 0 { - // Likely EBADF when already closed. In that case, the lock is released and all is fine. - return Ok(()); - } - libc::flock(fd, libc::LOCK_UN) - }; - if result < 0 { + let f = locks.remove(&l.id).unwrap(); + if let Err(_) = f.unlock() { return err(StatusCode::LockError, &format!("unlock failed: {}", l.id)); } Ok(())
--- a/src/env.rs Tue Mar 24 07:09:47 2020 +0100 +++ b/src/env.rs Mon May 18 23:43:14 2020 +0100 @@ -5,19 +5,30 @@ use std::fs::File; use std::io::prelude::*; +#[cfg(unix)] use std::os::unix::fs::FileExt; +#[cfg(windows)] +use std::os::windows::fs::FileExt; use std::path::{Path, PathBuf}; pub trait RandomAccess { fn read_at(&self, off: usize, dst: &mut [u8]) -> Result<usize>; } +#[cfg(unix)] impl RandomAccess for File { fn read_at(&self, off: usize, dst: &mut [u8]) -> Result<usize> { Ok((self as &dyn FileExt).read_at(dst, off as u64)?) } } +#[cfg(windows)] +impl RandomAccess for File { + fn read_at(&self, off: usize, dst: &mut [u8]) -> Result<usize> { + Ok((self as &dyn FileExt).seek_read(dst, off as u64)?) + } +} + pub struct FileLock { pub id: String, }
--- a/src/lib.rs Tue Mar 24 07:09:47 2020 +0100 +++ b/src/lib.rs Mon May 18 23:43:14 2020 +0100 @@ -26,9 +26,9 @@ extern crate crc; extern crate errno; extern crate integer_encoding; -extern crate libc; extern crate rand; extern crate snap; +extern crate fs2; #[cfg(test)] #[macro_use]
--- a/src/version_set.rs Tue Mar 24 07:09:47 2020 +0100 +++ b/src/version_set.rs Mon May 18 23:43:14 2020 +0100 @@ -18,8 +18,6 @@ use std::path::{Path, PathBuf}; use std::rc::Rc; -use std::os::unix::ffi::OsStrExt; - pub struct Compaction { level: usize, max_file_size: usize, @@ -888,8 +886,8 @@ let tempfile = temp_file_name(dbname, manifest_file_num); { let mut f = env.open_writable_file(Path::new(&tempfile))?; - f.write(manifest_base.as_os_str().as_bytes())?; - f.write("\n".as_bytes())?; + f.write_all(manifest_base.display().to_string().as_bytes())?; + f.write_all(b"\n")?; } let currentfile = current_file_name(dbname); if let Err(e) = env.rename(Path::new(&tempfile), Path::new(¤tfile)) {