Skip to content

Commit 2ecbc56

Browse files
committed
Change MainThread<T> abstraction
Don't force the internal use of `RefCell<T>`, let the caller place that into `MainThread<>` manually. This lets us remove the reference to `MainThread<>` from the definition of `Screen` again and reduces the number of `assert_is_main_thread()` calls.
1 parent 5c94ebd commit 2ecbc56

File tree

4 files changed

+47
-59
lines changed

4 files changed

+47
-59
lines changed

src/output.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use crate::env::EnvVar;
66
use crate::threads::MainThread;
77
use crate::wchar::prelude::*;
88
use bitflags::bitflags;
9+
use std::cell::RefCell;
910
use std::ffi::CStr;
1011
use std::io::{Result, Write};
1112
use std::os::fd::RawFd;
@@ -444,10 +445,10 @@ impl Outputter {
444445

445446
/// Access the outputter for stdout.
446447
/// This should only be used from the main thread.
447-
pub fn stdoutput() -> &'static MainThread<Outputter> {
448-
static STDOUTPUT: MainThread<Outputter> =
449-
MainThread::new(Outputter::new_from_fd(libc::STDOUT_FILENO));
450-
&STDOUTPUT
448+
pub fn stdoutput() -> &'static RefCell<Outputter> {
449+
static STDOUTPUT: MainThread<RefCell<Outputter>> =
450+
MainThread::new(RefCell::new(Outputter::new_from_fd(libc::STDOUT_FILENO)));
451+
STDOUTPUT.get()
451452
}
452453
}
453454

src/reader.rs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1902,7 +1902,8 @@ impl ReaderData {
19021902
perror("tcsetattr"); // return to previous mode
19031903
}
19041904
Outputter::stdoutput()
1905-
.with_mut(|output| output.set_color(RgbColor::RESET, RgbColor::RESET));
1905+
.borrow_mut()
1906+
.set_color(RgbColor::RESET, RgbColor::RESET);
19061907
}
19071908
rls.finished.then(|| zelf.command_line.text().to_owned())
19081909
}
@@ -2941,9 +2942,9 @@ impl ReaderData {
29412942
el.end_edit_group();
29422943
}
29432944
rl::DisableMouseTracking => {
2944-
Outputter::stdoutput().with_mut(|outp| {
2945-
outp.write_wstr(L!("\x1B[?1000l"));
2946-
});
2945+
Outputter::stdoutput()
2946+
.borrow_mut()
2947+
.write_wstr(L!("\x1B[?1000l"));
29472948
}
29482949
rl::ClearScreenAndRepaint => {
29492950
self.parser().libdata_mut().pods.is_repaint = true;
@@ -2954,9 +2955,7 @@ impl ReaderData {
29542955
// and *then* reexecute the prompt and overdraw it.
29552956
// This removes the flicker,
29562957
// while keeping the prompt up-to-date.
2957-
Outputter::stdoutput().with_mut(|outp| {
2958-
outp.write_wstr(&clear);
2959-
});
2958+
Outputter::stdoutput().borrow_mut().write_wstr(&clear);
29602959
self.screen.reset_line(/*repaint_prompt=*/ true);
29612960
self.layout_and_repaint(L!("readline"));
29622961
}
@@ -3488,9 +3487,9 @@ fn reader_interactive_init(parser: &Parser) {
34883487

34893488
/// Destroy data for interactive use.
34903489
fn reader_interactive_destroy() {
3491-
Outputter::stdoutput().with_mut(|outp| {
3492-
outp.set_color(RgbColor::RESET, RgbColor::RESET);
3493-
});
3490+
Outputter::stdoutput()
3491+
.borrow_mut()
3492+
.set_color(RgbColor::RESET, RgbColor::RESET);
34943493
}
34953494

34963495
/// \return whether fish is currently unwinding the stack in preparation to exit.
@@ -3571,9 +3570,9 @@ pub fn reader_write_title(
35713570
let _ = write_loop(&STDOUT_FILENO, &narrow);
35723571
}
35733572

3574-
Outputter::stdoutput().with_mut(|outp| {
3575-
outp.set_color(RgbColor::RESET, RgbColor::RESET);
3576-
});
3573+
Outputter::stdoutput()
3574+
.borrow_mut()
3575+
.set_color(RgbColor::RESET, RgbColor::RESET);
35773576
if reset_cursor_position && !lst.is_empty() {
35783577
// Put the cursor back at the beginning of the line (issue #2453).
35793578
let _ = write_to_fd(b"\r", STDOUT_FILENO);
@@ -4585,7 +4584,9 @@ fn reader_run_command(parser: &Parser, cmd: &wstr) -> EvalRes {
45854584
}
45864585

45874586
reader_write_title(cmd, parser, true);
4588-
Outputter::stdoutput().with_mut(|outp| outp.set_color(RgbColor::NORMAL, RgbColor::NORMAL));
4587+
Outputter::stdoutput()
4588+
.borrow_mut()
4589+
.set_color(RgbColor::NORMAL, RgbColor::NORMAL);
45894590
term_donate(false);
45904591

45914592
let time_before = Instant::now();

src/screen.rs

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
//! of text around to handle text insertion.
99
1010
use crate::pager::{PageRendering, Pager};
11-
use crate::threads::MainThread;
11+
use std::cell::RefCell;
1212
use std::collections::LinkedList;
1313
use std::ffi::{CStr, CString};
1414
use std::io::Write;
@@ -177,7 +177,7 @@ pub struct Screen {
177177
pub autosuggestion_is_truncated: bool,
178178

179179
/// Receiver for our output.
180-
outp: &'static MainThread<Outputter>,
180+
outp: &'static RefCell<Outputter>,
181181

182182
/// The internal representation of the desired screen contents.
183183
desired: ScreenData,
@@ -638,9 +638,9 @@ impl Screen {
638638
// Either issue a cr to go back to the beginning of this line, or a nl to go to the
639639
// beginning of the next one, depending on what we think is more efficient.
640640
if new_y <= zelf.actual.cursor.y {
641-
zelf.outp.with_mut(|outp| outp.push(b'\r'));
641+
zelf.outp.borrow_mut().push(b'\r');
642642
} else {
643-
zelf.outp.with_mut(|outp| outp.push(b'\n'));
643+
zelf.outp.borrow_mut().push(b'\n');
644644
zelf.actual.cursor.y += 1;
645645
}
646646
// Either way we're not in the first column.
@@ -674,16 +674,14 @@ impl Screen {
674674
None
675675
};
676676

677-
zelf.outp.with_mut(|outp| {
678-
for _ in 0..y_steps.abs_diff(0) {
679-
outp.tputs_if_some(&s);
680-
}
681-
});
677+
for _ in 0..y_steps.abs_diff(0) {
678+
zelf.outp.borrow_mut().tputs_if_some(&s);
679+
}
682680

683681
let mut x_steps =
684682
isize::try_from(new_x).unwrap() - isize::try_from(zelf.actual.cursor.x).unwrap();
685683
if x_steps != 0 && new_x == 0 {
686-
zelf.outp.with_mut(|outp| outp.push(b'\r'));
684+
zelf.outp.borrow_mut().push(b'\r');
687685
x_steps = 0;
688686
}
689687

@@ -703,10 +701,10 @@ impl Screen {
703701
multi_str.as_ref().unwrap(),
704702
i32::try_from(x_steps.abs_diff(0)).unwrap(),
705703
);
706-
zelf.outp.with_mut(|outp| outp.tputs_if_some(&multi_param));
704+
zelf.outp.borrow_mut().tputs_if_some(&multi_param);
707705
} else {
708706
for _ in 0..x_steps.abs_diff(0) {
709-
zelf.outp.with_mut(|outp| outp.tputs_if_some(&s));
707+
zelf.outp.borrow_mut().tputs_if_some(&s);
710708
}
711709
}
712710

@@ -718,7 +716,7 @@ impl Screen {
718716
fn write_char(&mut self, c: char, width: isize) {
719717
let mut zelf = self.scoped_buffer();
720718
zelf.actual.cursor.x = zelf.actual.cursor.x.wrapping_add(width as usize);
721-
zelf.outp.with_mut(|outp| outp.writech(c));
719+
zelf.outp.borrow_mut().writech(c);
722720
if Some(zelf.actual.cursor.x) == zelf.actual.screen_width && allow_soft_wrap() {
723721
zelf.soft_wrap_location = Some(Cursor {
724722
x: 0,
@@ -735,16 +733,16 @@ impl Screen {
735733

736734
/// Send the specified string through tputs and append the output to the screen's outputter.
737735
fn write_mbs(&mut self, s: &CStr) {
738-
self.outp.with_mut(|outp| outp.tputs(s));
736+
self.outp.borrow_mut().tputs(s);
739737
}
740738

741739
fn write_mbs_if_some(&mut self, s: &Option<impl AsRef<CStr>>) -> bool {
742-
self.outp.with_mut(|outp| outp.tputs_if_some(s))
740+
self.outp.borrow_mut().tputs_if_some(s)
743741
}
744742

745743
/// Convert a wide string to a multibyte string and append it to the buffer.
746744
fn write_str(&mut self, s: &wstr) {
747-
self.outp.with_mut(|outp| outp.write_wstr(s));
745+
self.outp.borrow_mut().write_wstr(s);
748746
}
749747

750748
/// Update the cursor as if soft wrapping had been performed.
@@ -769,9 +767,9 @@ impl Screen {
769767
}
770768

771769
fn scoped_buffer(&mut self) -> impl ScopeGuarding<Target = &mut Screen> {
772-
self.outp.with_mut(Outputter::begin_buffering);
770+
self.outp.borrow_mut().begin_buffering();
773771
ScopeGuard::new(self, |zelf| {
774-
zelf.outp.with_mut(Outputter::end_buffering);
772+
zelf.outp.borrow_mut().end_buffering();
775773
})
776774
}
777775

@@ -782,7 +780,7 @@ impl Screen {
782780
let mut set_color = |zelf: &mut Self, c| {
783781
let fg = color_resolver.resolve_spec(&c, false, vars);
784782
let bg = color_resolver.resolve_spec(&c, true, vars);
785-
zelf.outp.with_mut(|outp| outp.set_color(fg, bg));
783+
zelf.outp.borrow_mut().set_color(fg, bg);
786784
};
787785

788786
let mut cached_layouts = LAYOUT_CACHE_SHARED.lock().unwrap();
@@ -837,9 +835,9 @@ impl Screen {
837835
let mut start = 0;
838836
for line_break in left_prompt_layout.line_breaks {
839837
zelf.write_str(&left_prompt[start..line_break]);
840-
zelf.outp.with_mut(|outp| {
841-
outp.tputs_if_some(&term.and_then(|term| term.clr_eol.as_ref()));
842-
});
838+
zelf.outp
839+
.borrow_mut()
840+
.tputs_if_some(&term.and_then(|term| term.clr_eol.as_ref()));
843841
start = line_break;
844842
}
845843
zelf.write_str(&left_prompt[start..]);
@@ -1071,9 +1069,9 @@ impl Screen {
10711069

10721070
/// Issues an immediate clr_eos.
10731071
pub fn screen_force_clear_to_end() {
1074-
Outputter::stdoutput().with_mut(|outp| {
1075-
outp.tputs_if_some(&term().unwrap().clr_eos);
1076-
});
1072+
Outputter::stdoutput()
1073+
.borrow_mut()
1074+
.tputs_if_some(&term().unwrap().clr_eos);
10771075
}
10781076

10791077
/// Information about the layout of a prompt.

src/threads.rs

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
use crate::flog::{FloggableDebug, FLOG};
55
use crate::reader::ReaderData;
66
use once_cell::race::OnceBox;
7-
use std::cell::RefCell;
87
use std::marker::PhantomData;
98
use std::num::NonZeroU64;
109
use std::sync::atomic::{AtomicBool, Ordering};
@@ -363,7 +362,7 @@ impl ThreadPool {
363362
/// A `Sync` and `Send` wrapper for non-`Sync`/`Send` types.
364363
/// Only allows access from the main thread.
365364
pub struct MainThread<T> {
366-
data: RefCell<T>,
365+
data: T,
367366
// Make type !Send and !Sync by default
368367
_marker: PhantomData<*const ()>,
369368
}
@@ -376,25 +375,14 @@ unsafe impl<T: 'static> Sync for MainThread<T> {}
376375
impl<T> MainThread<T> {
377376
pub const fn new(value: T) -> Self {
378377
Self {
379-
data: RefCell::new(value),
378+
data: value,
380379
_marker: PhantomData,
381380
}
382381
}
383382

384-
pub fn with<F, R>(&self, f: F) -> R
385-
where
386-
F: FnOnce(&T) -> R,
387-
{
388-
assert_is_main_thread();
389-
f(&self.data.borrow())
390-
}
391-
392-
pub fn with_mut<F, R>(&self, f: F) -> R
393-
where
394-
F: FnOnce(&mut T) -> R,
395-
{
383+
pub fn get(&self) -> &T {
396384
assert_is_main_thread();
397-
f(&mut self.data.borrow_mut())
385+
&self.data
398386
}
399387
}
400388

0 commit comments

Comments
 (0)