chore: eliminate thread_local!

This commit is contained in:
Shunsuke Shibayama 2023-06-10 16:07:50 +09:00
parent d6f30924f1
commit 393a018fb9
5 changed files with 63 additions and 84 deletions

View file

@ -1,6 +1,5 @@
use std::cell::RefCell;
use std::io;
use std::io::{stdin, stdout, BufRead, Read, StdinLock, StdoutLock, Write};
use std::io::{stdin, stdout, BufRead, Read, Write};
use std::ops::Not;
use std::path::{Path, PathBuf};
use std::str::FromStr;
@ -123,39 +122,24 @@ macro_rules! _log {
};
}
thread_local! {
static INPUT: RefCell<StdinLock<'static>> = RefCell::new(stdin().lock());
static OUTPUT: RefCell<StdoutLock<'static>> = RefCell::new(stdout().lock());
}
fn send_stdout<T: ?Sized + Serialize>(message: &T) -> ELSResult<()> {
let msg = serde_json::to_string(message)?;
OUTPUT.with(|out| {
write!(
out.borrow_mut(),
"Content-Length: {}\r\n\r\n{}",
msg.len(),
msg
)?;
out.borrow_mut().flush()?;
Ok(())
})
let mut stdout = stdout().lock();
write!(stdout, "Content-Length: {}\r\n\r\n{}", msg.len(), msg)?;
stdout.flush()?;
Ok(())
}
fn read_line() -> io::Result<String> {
let mut line = String::new();
INPUT.with(|input| {
input.borrow_mut().read_line(&mut line)?;
Ok(line)
})
stdin().lock().read_line(&mut line)?;
Ok(line)
}
fn read_exact(len: usize) -> io::Result<Vec<u8>> {
let mut buf = vec![0; len];
INPUT.with(|input| {
input.borrow_mut().read_exact(&mut buf)?;
Ok(buf)
})
stdin().lock().read_exact(&mut buf)?;
Ok(buf)
}
pub(crate) fn send<T: ?Sized + Serialize>(message: &T) -> ELSResult<()> {
@ -228,7 +212,7 @@ impl<Checker: BuildRunnable, Parser: Parsable> Server<Checker, Parser> {
comp_cache: CompletionCache::new(cfg.copy()),
cfg,
home: normalize_path(std::env::current_dir().unwrap_or_default()),
erg_path: erg_path(), // already normalized
erg_path: erg_path().clone(), // already normalized
client_capas: ClientCapabilities::default(),
disabled_features: vec![],
opt_features: vec![],

View file

@ -1,5 +1,6 @@
use std::env::var;
use std::path::{Path, PathBuf};
use std::sync::OnceLock;
use crate::normalize_path;
use crate::python_util::get_sys_path;
@ -66,37 +67,35 @@ fn _python_site_packages() -> impl Iterator<Item = PathBuf> {
})
}
thread_local! {
pub static ERG_PATH: PathBuf = normalize_path(_erg_path());
pub static ERG_STD_PATH: PathBuf = normalize_path(_erg_std_path());
pub static ERG_STD_DECL_PATH: PathBuf = normalize_path(_erg_std_decl_path());
pub static ERG_PYSTD_PATH: PathBuf = normalize_path(_erg_pystd_path());
pub static ERG_EXTERNAL_LIB_PATH: PathBuf = normalize_path(_erg_external_lib_path());
pub static PYTHON_SITE_PACKAGES: Vec<PathBuf> = _python_site_packages().collect();
pub static ERG_PATH: OnceLock<PathBuf> = OnceLock::new();
pub static ERG_STD_PATH: OnceLock<PathBuf> = OnceLock::new();
pub static ERG_STD_DECL_PATH: OnceLock<PathBuf> = OnceLock::new();
pub static ERG_PYSTD_PATH: OnceLock<PathBuf> = OnceLock::new();
pub static ERG_EXTERNAL_LIB_PATH: OnceLock<PathBuf> = OnceLock::new();
pub static PYTHON_SITE_PACKAGES: OnceLock<Vec<PathBuf>> = OnceLock::new();
pub fn erg_path() -> &'static PathBuf {
ERG_PATH.get_or_init(|| normalize_path(_erg_path())) // .with(|s| s.clone())
}
pub fn erg_path() -> PathBuf {
ERG_PATH.with(|s| s.clone())
pub fn erg_std_path() -> &'static PathBuf {
ERG_STD_PATH.get_or_init(|| normalize_path(_erg_std_path()))
}
pub fn erg_std_path() -> PathBuf {
ERG_STD_PATH.with(|s| s.clone())
pub fn erg_std_decl_path() -> &'static PathBuf {
ERG_STD_DECL_PATH.get_or_init(|| normalize_path(_erg_std_decl_path()))
}
pub fn erg_std_decl_path() -> PathBuf {
ERG_STD_DECL_PATH.with(|s| s.clone())
pub fn erg_pystd_path() -> &'static PathBuf {
ERG_PYSTD_PATH.get_or_init(|| normalize_path(_erg_pystd_path()))
}
pub fn erg_pystd_path() -> PathBuf {
ERG_PYSTD_PATH.with(|s| s.clone())
pub fn erg_py_external_lib_path() -> &'static PathBuf {
ERG_EXTERNAL_LIB_PATH.get_or_init(|| normalize_path(_erg_external_lib_path()))
}
pub fn erg_py_external_lib_path() -> PathBuf {
ERG_EXTERNAL_LIB_PATH.with(|s| s.clone())
}
pub fn python_site_packages() -> Vec<PathBuf> {
PYTHON_SITE_PACKAGES.with(|s| s.clone())
pub fn python_site_packages() -> &'static Vec<PathBuf> {
PYTHON_SITE_PACKAGES.get_or_init(|| _python_site_packages().collect())
}
pub fn is_std_decl_path(path: &Path) -> bool {
@ -113,6 +112,5 @@ pub fn is_pystd_main_module(path: &Path) -> bool {
} else {
path.pop();
}
let pystd_path = erg_pystd_path();
path == pystd_path
path == erg_pystd_path().as_path()
}

View file

@ -604,7 +604,7 @@ impl Input {
/// 1. `site-packages/{path/to}.d.er`
/// 2. `site-packages/{path.d/to.d}/__init__.d.er`
fn resolve_std_decl_path(root: PathBuf, path: &Path) -> Option<PathBuf> {
fn resolve_std_decl_path(root: &Path, path: &Path) -> Option<PathBuf> {
let mut path = add_postfix_foreach(path, ".d");
path.set_extension("d.er"); // set_extension overrides the previous one
if let Ok(path) = root.join(&path).canonicalize() {
@ -629,7 +629,7 @@ impl Input {
///
/// e.g. `toml/encoder`
/// -> `site-packages/toml/__pycache__/encoder.d.er`, `site-packages/toml/encoder/__pycache__/__init__.d.er`
fn resolve_site_pkgs_decl_path(site_packages: PathBuf, path: &Path) -> Option<PathBuf> {
fn resolve_site_pkgs_decl_path(site_packages: &Path, path: &Path) -> Option<PathBuf> {
let dir = path.parent().unwrap_or_else(|| Path::new(""));
let mut file_path = PathBuf::from(path.file_stem().unwrap_or_default());
file_path.set_extension("d.er"); // set_extension overrides the previous one

View file

@ -1,5 +1,4 @@
use std::cell::RefCell;
use std::thread::LocalKey;
use std::sync::OnceLock;
#[cfg(not(feature = "full-repl"))]
use std::io::{stdin, BufRead, BufReader};
@ -18,6 +17,8 @@ use std::process::Command;
#[cfg(feature = "full-repl")]
use std::process::Output;
use crate::shared::AtomicShared;
/// e.g.
/// ```erg
/// >>> print! 1
@ -261,57 +262,56 @@ impl StdinReader {
}
}
thread_local! {
static READER: RefCell<StdinReader> = RefCell::new(StdinReader{
block_begin: 1,
lineno: 1,
buf: vec![],
#[cfg(feature = "full-repl")]
history_input_position: 1,
indent: 1
});
}
#[derive(Debug)]
pub struct GlobalStdin(LocalKey<RefCell<StdinReader>>);
pub struct GlobalStdin(OnceLock<AtomicShared<StdinReader>>);
pub static GLOBAL_STDIN: GlobalStdin = GlobalStdin(READER);
pub static GLOBAL_STDIN: GlobalStdin = GlobalStdin(OnceLock::new());
impl GlobalStdin {
fn get(&'static self) -> &'static AtomicShared<StdinReader> {
self.0.get_or_init(|| {
AtomicShared::new(StdinReader {
block_begin: 1,
lineno: 1,
buf: vec![],
#[cfg(feature = "full-repl")]
history_input_position: 1,
indent: 1,
})
})
}
pub fn read(&'static self) -> String {
self.0.with(|s| s.borrow_mut().read())
self.get().borrow_mut().read()
}
pub fn reread(&'static self) -> String {
self.0.with(|s| s.borrow().reread())
self.get().borrow_mut().reread()
}
pub fn reread_lines(&'static self, ln_begin: usize, ln_end: usize) -> Vec<String> {
self.0
.with(|s| s.borrow_mut().reread_lines(ln_begin, ln_end))
self.get().borrow_mut().reread_lines(ln_begin, ln_end)
}
pub fn lineno(&'static self) -> usize {
self.0.with(|s| s.borrow().lineno)
self.get().borrow_mut().lineno
}
pub fn block_begin(&'static self) -> usize {
self.0.with(|s| s.borrow().block_begin)
self.get().borrow_mut().block_begin
}
pub fn set_block_begin(&'static self, n: usize) {
self.0.with(|s| s.borrow_mut().block_begin = n);
self.get().borrow_mut().block_begin = n;
}
pub fn set_indent(&'static self, n: usize) {
self.0.with(|s| s.borrow_mut().indent = n as u16);
self.get().borrow_mut().indent = n as u16;
}
pub fn insert_whitespace(&'static self, whitespace: &str) {
self.0.with(|s| {
if let Some(line) = s.borrow_mut().last_line() {
line.insert_str(0, whitespace);
}
})
if let Some(line) = self.get().borrow_mut().last_line() {
line.insert_str(0, whitespace);
}
}
}

View file

@ -15,6 +15,7 @@ use std::path::PathBuf;
use erg_common::config::ErgConfig;
use erg_common::consts::{DEBUG_MODE, ERG_MODE, PYTHON_MODE};
use erg_common::dict;
use erg_common::env::erg_std_decl_path;
use erg_common::error::Location;
#[allow(unused_imports)]
use erg_common::log;
@ -515,10 +516,6 @@ pub fn builtins_path() -> PathBuf {
erg_common::env::erg_pystd_path().join("builtins.d.er")
}
pub fn std_decl_path() -> PathBuf {
erg_common::env::erg_std_decl_path()
}
impl Context {
fn register_builtin_decl(
&mut self,
@ -667,7 +664,7 @@ impl Context {
let module = if &self.name[..] == "<builtins>" {
builtins_path()
} else {
std_decl_path().join(format!("{}.d.er", self.name))
erg_std_decl_path().join(format!("{}.d.er", self.name))
};
let abs_loc = AbsLocation::new(Some(module), loc);
self.register_builtin_impl(name, t, muty, vis, py_name, abs_loc);