mirror of
https://github.com/lune-org/lune.git
synced 2025-04-02 01:20:56 +01:00
Fix deadlock in stdio.format calls in tostring metamethod (#288)
This commit is contained in:
parent
822dd19393
commit
dc08b91314
4 changed files with 27 additions and 7 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -1742,6 +1742,7 @@ dependencies = [
|
||||||
"dunce",
|
"dunce",
|
||||||
"mlua",
|
"mlua",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
"parking_lot",
|
||||||
"path-clean",
|
"path-clean",
|
||||||
"pathdiff",
|
"pathdiff",
|
||||||
"semver 1.0.23",
|
"semver 1.0.23",
|
||||||
|
|
|
@ -22,4 +22,5 @@ dunce = "1.0"
|
||||||
once_cell = "1.17"
|
once_cell = "1.17"
|
||||||
path-clean = "1.0"
|
path-clean = "1.0"
|
||||||
pathdiff = "0.2"
|
pathdiff = "0.2"
|
||||||
|
parking_lot = "0.12.3"
|
||||||
semver = "1.0"
|
semver = "1.0"
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
use std::{
|
use std::{collections::HashSet, sync::Arc};
|
||||||
collections::HashSet,
|
|
||||||
sync::{Arc, Mutex},
|
|
||||||
};
|
|
||||||
|
|
||||||
use console::{colors_enabled as get_colors_enabled, set_colors_enabled};
|
use console::{colors_enabled as get_colors_enabled, set_colors_enabled};
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
|
use parking_lot::ReentrantMutex;
|
||||||
|
|
||||||
mod basic;
|
mod basic;
|
||||||
mod config;
|
mod config;
|
||||||
|
@ -20,7 +18,7 @@ pub use self::config::ValueFormatConfig;
|
||||||
// NOTE: Since the setting for colors being enabled is global,
|
// NOTE: Since the setting for colors being enabled is global,
|
||||||
// and these functions may be called in parallel, we use this global
|
// and these functions may be called in parallel, we use this global
|
||||||
// lock to make sure that we don't mess up the colors for other threads.
|
// lock to make sure that we don't mess up the colors for other threads.
|
||||||
static COLORS_LOCK: Lazy<Arc<Mutex<()>>> = Lazy::new(|| Arc::new(Mutex::new(())));
|
static COLORS_LOCK: Lazy<Arc<ReentrantMutex<()>>> = Lazy::new(|| Arc::new(ReentrantMutex::new(())));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Formats a Lua value into a pretty string using the given config.
|
Formats a Lua value into a pretty string using the given config.
|
||||||
|
@ -28,7 +26,7 @@ static COLORS_LOCK: Lazy<Arc<Mutex<()>>> = Lazy::new(|| Arc::new(Mutex::new(()))
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[allow(clippy::missing_panics_doc)]
|
#[allow(clippy::missing_panics_doc)]
|
||||||
pub fn pretty_format_value(value: &LuaValue, config: &ValueFormatConfig) -> String {
|
pub fn pretty_format_value(value: &LuaValue, config: &ValueFormatConfig) -> String {
|
||||||
let _guard = COLORS_LOCK.lock().unwrap();
|
let _guard = COLORS_LOCK.lock();
|
||||||
|
|
||||||
let were_colors_enabled = get_colors_enabled();
|
let were_colors_enabled = get_colors_enabled();
|
||||||
set_colors_enabled(were_colors_enabled && config.colors_enabled);
|
set_colors_enabled(were_colors_enabled && config.colors_enabled);
|
||||||
|
@ -48,7 +46,7 @@ pub fn pretty_format_value(value: &LuaValue, config: &ValueFormatConfig) -> Stri
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[allow(clippy::missing_panics_doc)]
|
#[allow(clippy::missing_panics_doc)]
|
||||||
pub fn pretty_format_multi_value(values: &LuaMultiValue, config: &ValueFormatConfig) -> String {
|
pub fn pretty_format_multi_value(values: &LuaMultiValue, config: &ValueFormatConfig) -> String {
|
||||||
let _guard = COLORS_LOCK.lock().unwrap();
|
let _guard = COLORS_LOCK.lock();
|
||||||
|
|
||||||
let were_colors_enabled = get_colors_enabled();
|
let were_colors_enabled = get_colors_enabled();
|
||||||
set_colors_enabled(were_colors_enabled && config.colors_enabled);
|
set_colors_enabled(were_colors_enabled && config.colors_enabled);
|
||||||
|
|
|
@ -122,3 +122,23 @@ stdio.ewrite(typeof(errorMessage))
|
||||||
assertContains("Should format errors similarly to userdata", stdio.format(errorMessage), "<LuaErr")
|
assertContains("Should format errors similarly to userdata", stdio.format(errorMessage), "<LuaErr")
|
||||||
assertContains("Should format errors with stack begins", stdio.format(errorMessage), "Stack Begin")
|
assertContains("Should format errors with stack begins", stdio.format(errorMessage), "Stack Begin")
|
||||||
assertContains("Should format errors with stack ends", stdio.format(errorMessage), "Stack End")
|
assertContains("Should format errors with stack ends", stdio.format(errorMessage), "Stack End")
|
||||||
|
|
||||||
|
-- Check that calling stdio.format in a __tostring metamethod by print doesn't cause a deadlock
|
||||||
|
|
||||||
|
local inner = {}
|
||||||
|
setmetatable(inner, {
|
||||||
|
__tostring = function()
|
||||||
|
return stdio.format(5)
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
print(inner)
|
||||||
|
|
||||||
|
local outer = {}
|
||||||
|
setmetatable(outer, {
|
||||||
|
__tostring = function()
|
||||||
|
return stdio.format(inner)
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
print(outer)
|
||||||
|
|
Loading…
Add table
Reference in a new issue