Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

std: Add a new top-level thread_local module #19094

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions src/liblog/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@

extern crate regex;

use regex::Regex;
use std::cell::RefCell;
use std::fmt;
use std::io::LineBufferedWriter;
use std::io;
Expand All @@ -181,6 +181,8 @@ use std::rt;
use std::slice;
use std::sync::{Once, ONCE_INIT};

use regex::Regex;

use directive::LOG_LEVEL_NAMES;

pub mod macros;
Expand Down Expand Up @@ -213,7 +215,9 @@ pub const WARN: u32 = 2;
/// Error log level
pub const ERROR: u32 = 1;

local_data_key!(local_logger: Box<Logger + Send>)
thread_local!(static LOCAL_LOGGER: RefCell<Option<Box<Logger + Send>>> = {
RefCell::new(None)
})

/// A trait used to represent an interface to a task-local logger. Each task
/// can have its own custom logger which can respond to logging messages
Expand Down Expand Up @@ -283,7 +287,9 @@ pub fn log(level: u32, loc: &'static LogLocation, args: &fmt::Arguments) {
// Completely remove the local logger from TLS in case anyone attempts to
// frob the slot while we're doing the logging. This will destroy any logger
// set during logging.
let mut logger = local_logger.replace(None).unwrap_or_else(|| {
let mut logger = LOCAL_LOGGER.with(|s| {
s.borrow_mut().take()
}).unwrap_or_else(|| {
box DefaultLogger { handle: io::stderr() } as Box<Logger + Send>
});
logger.log(&LogRecord {
Expand All @@ -293,7 +299,7 @@ pub fn log(level: u32, loc: &'static LogLocation, args: &fmt::Arguments) {
module_path: loc.module_path,
line: loc.line,
});
local_logger.replace(Some(logger));
set_logger(logger);
}

/// Getter for the global log level. This is a function so that it can be called
Expand All @@ -305,7 +311,10 @@ pub fn log_level() -> u32 { unsafe { LOG_LEVEL } }
/// Replaces the task-local logger with the specified logger, returning the old
/// logger.
pub fn set_logger(logger: Box<Logger + Send>) -> Option<Box<Logger + Send>> {
local_logger.replace(Some(logger))
let mut l = Some(logger);
LOCAL_LOGGER.with(|slot| {
mem::replace(&mut *slot.borrow_mut(), l.take())
})
}

/// A LogRecord is created by the logging macros, and passed as the only
Expand Down
13 changes: 8 additions & 5 deletions src/librustc/util/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

#![allow(non_camel_case_types)]

use std::cell::RefCell;
use std::cell::{RefCell, Cell};
use std::collections::HashMap;
use std::fmt::Show;
use std::hash::{Hash, Hasher};
Expand All @@ -26,11 +26,14 @@ use syntax::visit::Visitor;
pub struct ErrorReported;

pub fn time<T, U>(do_it: bool, what: &str, u: U, f: |U| -> T) -> T {
local_data_key!(depth: uint);
thread_local!(static DEPTH: Cell<uint> = Cell::new(0));
if !do_it { return f(u); }

let old = depth.get().map(|d| *d).unwrap_or(0);
depth.replace(Some(old + 1));
let old = DEPTH.with(|slot| {
let r = slot.get();
slot.set(r + 1);
r
});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not bad :)


let mut u = Some(u);
let mut rv = None;
Expand All @@ -41,7 +44,7 @@ pub fn time<T, U>(do_it: bool, what: &str, u: U, f: |U| -> T) -> T {

println!("{}time: {}.{:03} \t{}", " ".repeat(old),
dur.num_seconds(), dur.num_milliseconds() % 1000, what);
depth.replace(Some(old));
DEPTH.with(|slot| slot.set(old));

rv
}
Expand Down
35 changes: 21 additions & 14 deletions src/librustc_trans/trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,17 +100,20 @@ use syntax::visit::Visitor;
use syntax::visit;
use syntax::{ast, ast_util, ast_map};

local_data_key!(task_local_insn_key: RefCell<Vec<&'static str>>)
thread_local!(static TASK_LOCAL_INSN_KEY: RefCell<Option<Vec<&'static str>>> = {
RefCell::new(None)
})

pub fn with_insn_ctxt(blk: |&[&'static str]|) {
match task_local_insn_key.get() {
Some(ctx) => blk(ctx.borrow().as_slice()),
None => ()
}
TASK_LOCAL_INSN_KEY.with(|slot| {
slot.borrow().as_ref().map(|s| blk(s.as_slice()));
})
}

pub fn init_insn_ctxt() {
task_local_insn_key.replace(Some(RefCell::new(Vec::new())));
TASK_LOCAL_INSN_KEY.with(|slot| {
*slot.borrow_mut() = Some(Vec::new());
});
}

pub struct _InsnCtxt {
Expand All @@ -120,19 +123,23 @@ pub struct _InsnCtxt {
#[unsafe_destructor]
impl Drop for _InsnCtxt {
fn drop(&mut self) {
match task_local_insn_key.get() {
Some(ctx) => { ctx.borrow_mut().pop(); }
None => {}
}
TASK_LOCAL_INSN_KEY.with(|slot| {
match slot.borrow_mut().as_mut() {
Some(ctx) => { ctx.pop(); }
None => {}
}
})
}
}

pub fn push_ctxt(s: &'static str) -> _InsnCtxt {
debug!("new InsnCtxt: {}", s);
match task_local_insn_key.get() {
Some(ctx) => ctx.borrow_mut().push(s),
None => {}
}
TASK_LOCAL_INSN_KEY.with(|slot| {
match slot.borrow_mut().as_mut() {
Some(ctx) => ctx.push(s),
None => {}
}
});
_InsnCtxt { _cannot_construct_outside_of_this_module: () }
}

Expand Down
26 changes: 12 additions & 14 deletions src/librustdoc/html/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use stability_summary::ModuleSummary;
use html::item_type;
use html::item_type::ItemType;
use html::render;
use html::render::{cache_key, current_location_key};
use html::render::{cache, CURRENT_LOCATION_KEY};

/// Helper to render an optional visibility with a space after it (if the
/// visibility is preset)
Expand Down Expand Up @@ -236,9 +236,9 @@ fn path(w: &mut fmt::Formatter, path: &clean::Path, print_all: bool,
generics.push_str("&gt;");
}

let loc = current_location_key.get().unwrap();
let cache = cache_key.get().unwrap();
let abs_root = root(&**cache, loc.as_slice());
let loc = CURRENT_LOCATION_KEY.with(|l| l.borrow().clone());
let cache = cache();
let abs_root = root(&*cache, loc.as_slice());
let rel_root = match path.segments[0].name.as_slice() {
"self" => Some("./".to_string()),
_ => None,
Expand Down Expand Up @@ -271,7 +271,7 @@ fn path(w: &mut fmt::Formatter, path: &clean::Path, print_all: bool,
}
}

match info(&**cache) {
match info(&*cache) {
// This is a documented path, link to it!
Some((ref fqp, shortty)) if abs_root.is_some() => {
let mut url = String::from_str(abs_root.unwrap().as_slice());
Expand Down Expand Up @@ -308,12 +308,12 @@ fn path(w: &mut fmt::Formatter, path: &clean::Path, print_all: bool,
fn primitive_link(f: &mut fmt::Formatter,
prim: clean::PrimitiveType,
name: &str) -> fmt::Result {
let m = cache_key.get().unwrap();
let m = cache();
let mut needs_termination = false;
match m.primitive_locations.get(&prim) {
Some(&ast::LOCAL_CRATE) => {
let loc = current_location_key.get().unwrap();
let len = if loc.len() == 0 {0} else {loc.len() - 1};
let len = CURRENT_LOCATION_KEY.with(|s| s.borrow().len());
let len = if len == 0 {0} else {len - 1};
try!(write!(f, "<a href='{}primitive.{}.html'>",
"../".repeat(len),
prim.to_url_str()));
Expand All @@ -327,8 +327,8 @@ fn primitive_link(f: &mut fmt::Formatter,
let loc = match m.extern_locations[cnum] {
render::Remote(ref s) => Some(s.to_string()),
render::Local => {
let loc = current_location_key.get().unwrap();
Some("../".repeat(loc.len()))
let len = CURRENT_LOCATION_KEY.with(|s| s.borrow().len());
Some("../".repeat(len))
}
render::Unknown => None,
};
Expand Down Expand Up @@ -371,12 +371,10 @@ impl fmt::Show for clean::Type {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
clean::TyParamBinder(id) => {
let m = cache_key.get().unwrap();
f.write(m.typarams[ast_util::local_def(id)].as_bytes())
f.write(cache().typarams[ast_util::local_def(id)].as_bytes())
}
clean::Generic(did) => {
let m = cache_key.get().unwrap();
f.write(m.typarams[did].as_bytes())
f.write(cache().typarams[did].as_bytes())
}
clean::ResolvedPath{ did, ref typarams, ref path } => {
try!(resolved_path(f, did, path, false));
Expand Down
55 changes: 31 additions & 24 deletions src/librustdoc/html/markdown.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,10 +147,14 @@ fn stripped_filtered_line<'a>(s: &'a str) -> Option<&'a str> {
}
}

local_data_key!(used_header_map: RefCell<HashMap<String, uint>>)
local_data_key!(test_idx: Cell<uint>)
// None == render an example, but there's no crate name
local_data_key!(pub playground_krate: Option<String>)
thread_local!(static USED_HEADER_MAP: RefCell<HashMap<String, uint>> = {
RefCell::new(HashMap::new())
})
thread_local!(static TEST_IDX: Cell<uint> = Cell::new(0))

thread_local!(pub static PLAYGROUND_KRATE: RefCell<Option<Option<String>>> = {
RefCell::new(None)
})

pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
extern fn block(ob: *mut hoedown_buffer, orig_text: *const hoedown_buffer,
Expand Down Expand Up @@ -183,12 +187,15 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
stripped_filtered_line(*l).is_none()
});
let text = lines.collect::<Vec<&str>>().connect("\n");
if !rendered {
if rendered { return }
PLAYGROUND_KRATE.with(|krate| {
let mut s = String::new();
let id = playground_krate.get().map(|krate| {
let idx = test_idx.get().unwrap();
let i = idx.get();
idx.set(i + 1);
let id = krate.borrow().as_ref().map(|krate| {
let idx = TEST_IDX.with(|slot| {
let i = slot.get();
slot.set(i + 1);
i
});

let test = origtext.lines().map(|l| {
stripped_filtered_line(l).unwrap_or(l)
Expand All @@ -197,15 +204,15 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
let test = test::maketest(test.as_slice(), krate, false, false);
s.push_str(format!("<span id='rust-example-raw-{}' \
class='rusttest'>{}</span>",
i, Escape(test.as_slice())).as_slice());
format!("rust-example-rendered-{}", i)
idx, Escape(test.as_slice())).as_slice());
format!("rust-example-rendered-{}", idx)
});
let id = id.as_ref().map(|a| a.as_slice());
s.push_str(highlight::highlight(text.as_slice(), None, id)
.as_slice());
let output = s.to_c_str();
hoedown_buffer_puts(ob, output.as_ptr());
}
})
}
}

Expand All @@ -229,18 +236,20 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {

// This is a terrible hack working around how hoedown gives us rendered
// html for text rather than the raw text.
let id = id.replace("<code>", "").replace("</code>", "").to_string();

let opaque = opaque as *mut hoedown_html_renderer_state;
let opaque = unsafe { &mut *((*opaque).opaque as *mut MyOpaque) };

// Make sure our hyphenated ID is unique for this page
let map = used_header_map.get().unwrap();
let id = match map.borrow_mut().get_mut(&id) {
None => id,
Some(a) => { *a += 1; format!("{}-{}", id, *a - 1) }
};
map.borrow_mut().insert(id.clone(), 1);
let id = USED_HEADER_MAP.with(|map| {
let id = id.replace("<code>", "").replace("</code>", "").to_string();
let id = match map.borrow_mut().get_mut(&id) {
None => id,
Some(a) => { *a += 1; format!("{}-{}", id, *a - 1) }
};
map.borrow_mut().insert(id.clone(), 1);
id
});

let sec = match opaque.toc_builder {
Some(ref mut builder) => {
Expand All @@ -262,9 +271,7 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
text.with_c_str(|p| unsafe { hoedown_buffer_puts(ob, p) });
}

if used_header_map.get().is_none() {
reset_headers();
}
reset_headers();

unsafe {
let ob = hoedown_buffer_new(DEF_OUNIT);
Expand Down Expand Up @@ -418,8 +425,8 @@ impl LangString {
/// used at the beginning of rendering an entire HTML page to reset from the
/// previous state (if any).
pub fn reset_headers() {
used_header_map.replace(Some(RefCell::new(HashMap::new())));
test_idx.replace(Some(Cell::new(0)));
USED_HEADER_MAP.with(|s| s.borrow_mut().clear());
TEST_IDX.with(|s| s.set(0));
}

impl<'a> fmt::Show for Markdown<'a> {
Expand Down
Loading