Mercurial > public > mercurial-scm > hg-stable
diff rust/hg-core/src/revlog/inner_revlog.rs @ 52780:549b58b1ce72
rust-inner-revlog: use threadlocals for file handles
In contexts where we access the same revlog from multiple threads
(like in `annotate`), multiple threads would lock the handle, then read from
a different place that they would expect, since the `seek` behavior of the
`InnerRevlog` was written with single threaded access in mind.
author | Rapha?l Gom?s <rgomes@octobus.net> |
---|---|
date | Fri, 24 Jan 2025 13:07:15 -0500 |
parents | 162f4801ad39 |
children | 8de68446a5bd |
line wrap: on
line diff
--- a/rust/hg-core/src/revlog/inner_revlog.rs Fri Jan 24 12:05:23 2025 -0500 +++ b/rust/hg-core/src/revlog/inner_revlog.rs Fri Jan 24 13:07:15 2025 -0500 @@ -829,16 +829,8 @@ #[doc(hidden)] pub fn exit_writing_context(&mut self) { self.writing_handles.take(); - self.segment_file - .writing_handle - .write() - .expect("lock is poisoned") - .take(); - self.segment_file - .reading_handle - .write() - .expect("lock is poisoned") - .take(); + self.segment_file.writing_handle.get().map(|h| h.take()); + self.segment_file.reading_handle.get().map(|h| h.take()); } /// `pub` only for use in hg-cpython @@ -904,8 +896,8 @@ *self .segment_file .reading_handle - .write() - .expect("lock is poisoned") = if self.is_inline() { + .get_or_default() + .borrow_mut() = if self.is_inline() { Some(index_handle) } else { data_handle @@ -985,11 +977,7 @@ if let Some(handles) = &mut self.writing_handles { handles.index_handle.flush()?; self.writing_handles.take(); - self.segment_file - .writing_handle - .write() - .expect("lock is poisoned") - .take(); + self.segment_file.writing_handle.get().map(|h| h.take()); } let mut new_data_file_handle = self.vfs.create(&self.data_file, true)?; @@ -1058,8 +1046,8 @@ *self .segment_file .writing_handle - .write() - .expect("lock is poisoned") = new_data_handle; + .get_or_default() + .borrow_mut() = new_data_handle; } Ok(self.index_file.to_owned())