summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndrew Gallant <jamslam@gmail.com>2016-10-11 18:23:49 -0400
committerAndrew Gallant <jamslam@gmail.com>2016-10-11 18:23:49 -0400
commit247a9398f4dd1903ed561aa1bb2ba088a70c5a79 (patch)
tree8a17614dc25dca1a3ae13dec60f660029efa01a2 /src
parent4981991a6e4d1808d54c8d20fc4d93fcf0c1abfe (diff)
Switch to thread_local crate in lieu of thread_local!.
This is to work around a bug where using a thread_local! was causing a segfault on macos. Fixes #164.
Diffstat (limited to 'src')
-rw-r--r--src/gitignore.rs38
-rw-r--r--src/main.rs1
2 files changed, 19 insertions, 20 deletions
diff --git a/src/gitignore.rs b/src/gitignore.rs
index 4c7e8203..9daeb3cb 100644
--- a/src/gitignore.rs
+++ b/src/gitignore.rs
@@ -27,9 +27,11 @@ use std::fmt;
use std::fs::File;
use std::io::{self, BufRead};
use std::path::{Path, PathBuf};
+use std::sync::Arc;
use globset::{self, Candidate, GlobBuilder, GlobSet, GlobSetBuilder};
use regex;
+use thread_local::ThreadLocal;
use pathutil::{is_file_name, strip_prefix};
@@ -87,6 +89,7 @@ pub struct Gitignore {
patterns: Vec<Pattern>,
num_ignores: u64,
num_whitelist: u64,
+ matches: Arc<ThreadLocal<RefCell<Vec<usize>>>>,
}
impl Gitignore {
@@ -133,27 +136,21 @@ impl Gitignore {
/// Like matched, but takes a path that has already been stripped.
pub fn matched_stripped(&self, path: &Path, is_dir: bool) -> Match {
- thread_local! {
- static MATCHES: RefCell<Vec<usize>> = {
- RefCell::new(vec![])
+ let _matches = self.matches.get_default();
+ let mut matches = _matches.borrow_mut();
+ let candidate = Candidate::new(path);
+ self.set.matches_candidate_into(&candidate, &mut *matches);
+ for &i in matches.iter().rev() {
+ let pat = &self.patterns[i];
+ if !pat.only_dir || is_dir {
+ return if pat.whitelist {
+ Match::Whitelist(pat)
+ } else {
+ Match::Ignored(pat)
+ };
}
- };
- MATCHES.with(|matches| {
- let mut matches = matches.borrow_mut();
- let candidate = Candidate::new(path);
- self.set.matches_candidate_into(&candidate, &mut *matches);
- for &i in matches.iter().rev() {
- let pat = &self.patterns[i];
- if !pat.only_dir || is_dir {
- return if pat.whitelist {
- Match::Whitelist(pat)
- } else {
- Match::Ignored(pat)
- };
- }
- }
- Match::None
- })
+ }
+ Match::None
}
/// Returns the total number of ignore patterns.
@@ -256,6 +253,7 @@ impl GitignoreBuilder {
patterns: self.patterns,
num_ignores: nignores as u64,
num_whitelist: nwhitelist as u64,
+ matches: Arc::new(ThreadLocal::default()),
})
}
diff --git a/src/main.rs b/src/main.rs
index c70a3c52..7a6ac021 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -16,6 +16,7 @@ extern crate num_cpus;
extern crate regex;
extern crate rustc_serialize;
extern crate term;
+extern crate thread_local;
extern crate walkdir;
#[cfg(windows)]
extern crate winapi;