##// END OF EJS Templates
rust-pathauditor: use interior mutability for use in multi-threaded contexts...
Raphaël Gomès -
r45022:07d9fd60 default
parent child Browse files
Show More
@@ -698,7 +698,7 b" pub fn status<'a: 'c, 'b: 'c, 'c>("
698 698 // We walked all dirs under the roots that weren't ignored, and
699 699 // everything that matched was stat'ed and is already in results.
700 700 // The rest must thus be ignored or under a symlink.
701 let mut path_auditor = PathAuditor::new(root_dir);
701 let path_auditor = PathAuditor::new(root_dir);
702 702
703 703 for (ref filename, entry) in to_visit {
704 704 // Report ignored items in the dmap as long as they are not
@@ -210,7 +210,7 b' pub fn canonical_path('
210 210 } else {
211 211 name.to_owned()
212 212 };
213 let mut auditor = PathAuditor::new(&root);
213 let auditor = PathAuditor::new(&root);
214 214 if name != root && name.starts_with(&root) {
215 215 let name = name.strip_prefix(&root).unwrap();
216 216 auditor.audit_path(path_to_hg_path_buf(name)?)?;
@@ -13,13 +13,14 b' use crate::utils::{'
13 13 };
14 14 use std::collections::HashSet;
15 15 use std::path::{Path, PathBuf};
16 use std::sync::{Mutex, RwLock};
16 17
17 18 /// Ensures that a path is valid for use in the repository i.e. does not use
18 19 /// any banned components, does not traverse a symlink, etc.
19 20 #[derive(Debug, Default)]
20 21 pub struct PathAuditor {
21 audited: HashSet<HgPathBuf>,
22 audited_dirs: HashSet<HgPathBuf>,
22 audited: Mutex<HashSet<HgPathBuf>>,
23 audited_dirs: RwLock<HashSet<HgPathBuf>>,
23 24 root: PathBuf,
24 25 }
25 26
@@ -31,7 +32,7 b' impl PathAuditor {'
31 32 }
32 33 }
33 34 pub fn audit_path(
34 &mut self,
35 &self,
35 36 path: impl AsRef<HgPath>,
36 37 ) -> Result<(), HgPathError> {
37 38 // TODO windows "localpath" normalization
@@ -40,7 +41,7 b' impl PathAuditor {'
40 41 return Ok(());
41 42 }
42 43 // TODO case normalization
43 if self.audited.contains(path) {
44 if self.audited.lock().unwrap().contains(path) {
44 45 return Ok(());
45 46 }
46 47 // AIX ignores "/" at end of path, others raise EISDIR.
@@ -113,14 +114,14 b' impl PathAuditor {'
113 114 for index in 0..parts.len() {
114 115 let prefix = &parts[..index + 1].join(&b'/');
115 116 let prefix = HgPath::new(prefix);
116 if self.audited_dirs.contains(prefix) {
117 if self.audited_dirs.read().unwrap().contains(prefix) {
117 118 continue;
118 119 }
119 120 self.check_filesystem(&prefix, &path)?;
120 self.audited_dirs.insert(prefix.to_owned());
121 self.audited_dirs.write().unwrap().insert(prefix.to_owned());
121 122 }
122 123
123 self.audited.insert(path.to_owned());
124 self.audited.lock().unwrap().insert(path.to_owned());
124 125
125 126 Ok(())
126 127 }
@@ -171,7 +172,7 b' impl PathAuditor {'
171 172 Ok(())
172 173 }
173 174
174 pub fn check(&mut self, path: impl AsRef<HgPath>) -> bool {
175 pub fn check(&self, path: impl AsRef<HgPath>) -> bool {
175 176 self.audit_path(path).is_ok()
176 177 }
177 178 }
@@ -184,7 +185,7 b' mod tests {'
184 185
185 186 #[test]
186 187 fn test_path_auditor() {
187 let mut auditor = PathAuditor::new(get_path_from_bytes(b"/tmp"));
188 let auditor = PathAuditor::new(get_path_from_bytes(b"/tmp"));
188 189
189 190 let path = HgPath::new(b".hg/00changelog.i");
190 191 assert_eq!(
General Comments 0
You need to be logged in to leave comments. Login now