Skip to content

Commit

Permalink
Switch to thread_local crate in lieu of thread_local!.
Browse files Browse the repository at this point in the history
This is to work around a bug where using a thread_local! was causing
a segfault on macos.

Fixes #164.
  • Loading branch information
BurntSushi committed Oct 11, 2016
1 parent 4981991 commit 247a939
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 21 deletions.
3 changes: 2 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ num_cpus = "1"
regex = "0.1.77"
rustc-serialize = "0.3"
term = "0.4"
thread_local = "0.2.7"
walkdir = "0.1"

[target.'cfg(windows)'.dependencies]
Expand Down
38 changes: 18 additions & 20 deletions src/gitignore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down Expand Up @@ -87,6 +89,7 @@ pub struct Gitignore {
patterns: Vec<Pattern>,
num_ignores: u64,
num_whitelist: u64,
matches: Arc<ThreadLocal<RefCell<Vec<usize>>>>,
}

impl Gitignore {
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -256,6 +253,7 @@ impl GitignoreBuilder {
patterns: self.patterns,
num_ignores: nignores as u64,
num_whitelist: nwhitelist as u64,
matches: Arc::new(ThreadLocal::default()),
})
}

Expand Down
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 247a939

Please sign in to comment.