Mercurial > lbo > hg > leveldb-rs
changeset 301:eea316cf8f50
db_impl: Move lockfile management into dedicated methods.
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Wed, 27 Sep 2017 05:29:43 +0000 |
parents | 8ed86e8a9a5e |
children | a82f7228192c |
files | src/db_impl.rs |
diffstat | 1 files changed, 37 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/src/db_impl.rs Wed Sep 27 05:25:52 2017 +0000 +++ b/src/db_impl.rs Wed Sep 27 05:29:43 2017 +0000 @@ -5,7 +5,7 @@ use cmp::{Cmp, InternalKeyCmp}; use env::{Env, FileLock}; -use error::{err, StatusCode, Result}; +use error::{err, Status, StatusCode, Result}; use filter::{BoxedFilterPolicy, InternalFilterPolicy}; use infolog::Logger; use log::{LogReader, LogWriter}; @@ -114,6 +114,31 @@ Ok(db) } + /// acquire_lock acquires the lock file. + fn acquire_lock(&mut self) -> Result<()> { + let lock_r = self.opt.env.lock(Path::new(&lock_file_name(&self.name))); + if let Ok(lockfile) = lock_r { + self.lock = Some(lockfile); + return Ok(()); + } + + let e = lock_r.unwrap_err(); + if e.code == StatusCode::LockError { + return err(StatusCode::LockError, + "database lock is held by another instance"); + } + e + } + + /// release_lock releases the lock file, if it's currently held. + fn release_lock(&mut self) -> Result<()> { + if let Some(l) = self.lock.take() { + self.opt.env.unlock(l) + } else { + Ok(()) + } + } + /// initialize_db initializes a new database. fn initialize_db(&mut self) -> Result<()> { let mut ve = VersionEdit::new(); @@ -136,8 +161,7 @@ /// log_and_apply() should be called after recovery has finished. fn recover(&mut self, ve: &mut VersionEdit) -> Result<bool> { self.opt.env.mkdir(Path::new(&self.name)).is_ok(); - let lockfile = self.opt.env.lock(Path::new(&lock_file_name(&self.name)))?; - self.lock = Some(lockfile); + self.acquire_lock()?; if let Err(e) = read_current_file(&self.opt.env, &self.name) { if e.code == StatusCode::NotFound && self.opt.create_if_missing { @@ -666,9 +690,7 @@ impl Drop for DB { fn drop(&mut self) { - if let Some(l) = self.lock.take() { - self.opt.env.unlock(l); - } + self.release_lock(); } } @@ -931,6 +953,15 @@ } #[test] + fn test_db_impl_locking() { + let opt = options::for_test(); + let db = DB::open("db", opt.clone()).unwrap(); + let want_err = Status::new(StatusCode::LockError, + "database lock is held by another instance"); + assert_eq!(want_err, DB::open("db", opt.clone()).err().unwrap()); + } + + #[test] fn test_db_impl_build_table() { let mut opt = options::for_test(); opt.block_size = 128;