Skip to content

Commit e87a2e6

Browse files
committed
LuaVMManager替换为递归锁解决循环调用死锁问题
1 parent 553e568 commit e87a2e6

File tree

3 files changed

+45
-19
lines changed

3 files changed

+45
-19
lines changed

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ mod tests;
2424

2525
fn panic_hook(info: &std::panic::PanicHookInfo) {
2626
let msg = format!("LuaFramework panic: {}", info);
27-
log::error!("{}", msg);
27+
log::error!("{:#}", msg);
2828
utility::show_error_msgbox(&msg, "LuaFramework Panic");
2929
}
3030

src/luavm.rs

Lines changed: 43 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::{
2+
cell::RefCell,
23
collections::{HashMap, HashSet},
34
path::Path,
45
sync::{Arc, LazyLock, Weak},
@@ -7,7 +8,7 @@ use std::{
78
use library::LuaModule;
89
use mlua::prelude::*;
910

10-
use parking_lot::Mutex;
11+
use parking_lot::{Mutex, ReentrantMutex};
1112
use rand::RngCore;
1213

1314
use crate::error::{Error, Result};
@@ -48,7 +49,7 @@ pub struct LastLoadInfo {
4849

4950
#[derive(Default)]
5051
pub struct LuaVMManager {
51-
inner: Mutex<LuaVMManagerInner>,
52+
inner: ReentrantMutex<RefCell<LuaVMManagerInner>>,
5253
last_load_info: Mutex<Option<LastLoadInfo>>,
5354
}
5455

@@ -67,14 +68,17 @@ impl LuaVMManager {
6768
/// name: 虚拟名称,用于标识虚拟机。会自动在前面加上 `virtual:`
6869
#[allow(dead_code)]
6970
pub fn create_virtual_vm(&self, name: &str) -> SharedLuaVM {
70-
let mut inner = self.inner.lock();
71-
7271
let virtual_name = format!("virtual:{}", name);
7372
let luavm = LuaVM::new_with_libs(&virtual_name).unwrap();
7473
let id = luavm.id();
7574

7675
let luavm_shared = Arc::new(luavm);
77-
inner.add_vm(id, &virtual_name, luavm_shared.clone());
76+
{
77+
let inner = self.inner.lock();
78+
inner
79+
.borrow_mut()
80+
.add_vm(id, &virtual_name, luavm_shared.clone());
81+
}
7882

7983
luavm_shared
8084
}
@@ -98,9 +102,13 @@ impl LuaVMManager {
98102
// 先向管理器添加虚拟机,以便初始化时有模块需要获取引用
99103
let id = luavm.id();
100104
let luavm_shared = Arc::new(luavm);
101-
self.inner
102-
.lock()
103-
.add_vm(id, &file_name, luavm_shared.clone());
105+
106+
{
107+
let inner = self.inner.lock();
108+
inner
109+
.borrow_mut()
110+
.add_vm(id, &file_name, luavm_shared.clone());
111+
}
104112

105113
{
106114
// 加载自定义库
@@ -125,9 +133,10 @@ impl LuaVMManager {
125133
pub fn get_vm_by_lua(&self, lua: &Lua) -> Option<SharedLuaVM> {
126134
let luaid = Self::get_id_from_lua(lua).ok()?;
127135
let inner = self.inner.lock();
128-
inner.vms.get(&luaid).cloned()
136+
let inner_b = inner.borrow();
137+
inner_b.vms.get(&luaid).cloned()
129138
}
130-
139+
///
131140
/// 扫描路径并加载所有虚拟机
132141
pub fn auto_load_vms<P>(&self, dir_path: P) -> Result<Vec<LuaVMId>>
133142
where
@@ -158,9 +167,12 @@ impl LuaVMManager {
158167

159168
// 检查是否被禁用
160169
let file_name = path.file_name().unwrap_or_default().to_string_lossy();
161-
if !self.inner.lock().is_vm_name_enabled(file_name.as_ref()) {
162-
log::debug!("Script file '{}' is disabled. Skipping.", file_name);
163-
continue;
170+
{
171+
let inner = self.inner.lock();
172+
if !inner.borrow().is_vm_name_enabled(file_name.as_ref()) {
173+
log::debug!("Script file '{}' is disabled. Skipping.", file_name);
174+
continue;
175+
}
164176
}
165177

166178
match self.create_vm_with_file(&path) {
@@ -183,7 +195,10 @@ impl LuaVMManager {
183195

184196
/// 重新加载所有虚拟机
185197
pub fn reload_physical_vms(&self) -> Result<()> {
186-
self.inner.lock().remove_pyhsical_vms();
198+
{
199+
let inner = self.inner.lock();
200+
inner.borrow_mut().remove_pyhsical_vms();
201+
}
187202
// 移除共享状态
188203
library::sdk::shared_state::SharedState::instance().clear_states();
189204
// 加载
@@ -199,7 +214,8 @@ impl LuaVMManager {
199214
/// 调用已设置的回调函数,无参数。
200215
pub fn invoke_fn(&self, fn_name: &str) {
201216
let inner = self.inner.lock();
202-
for (_, luavm) in inner.iter_vms() {
217+
let inner_b = inner.borrow();
218+
for (_, luavm) in inner_b.iter_vms() {
203219
let globals = luavm.lua().globals();
204220
let Ok(fun) = globals.get::<LuaFunction>(format!("_{fn_name}")) else {
205221
continue;
@@ -213,11 +229,21 @@ impl LuaVMManager {
213229
}
214230

215231
pub fn run_with_lock<F>(&self, f: F) -> LuaResult<()>
232+
where
233+
F: FnOnce(&LuaVMManagerInner) -> LuaResult<()>,
234+
{
235+
let inner = self.inner.lock();
236+
let inner_b = inner.borrow();
237+
f(&inner_b)
238+
}
239+
240+
pub fn run_with_lock_mut<F>(&self, f: F) -> LuaResult<()>
216241
where
217242
F: FnOnce(&mut LuaVMManagerInner) -> LuaResult<()>,
218243
{
219-
let mut inner = self.inner.lock();
220-
f(&mut inner)
244+
let inner = self.inner.lock();
245+
let mut inner_b = inner.borrow_mut();
246+
f(&mut inner_b)
221247
}
222248

223249
/// 从Lua中获取虚拟机ID

src/render_core/draw.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ fn draw_script_manager_tab(ui: &cimgui::Ui) {
7575
ui.text("Scripts");
7676

7777
let mut changed = false;
78-
let _ = LuaVMManager::instance().run_with_lock(|inner| {
78+
let _ = LuaVMManager::instance().run_with_lock_mut(|inner| {
7979
// Name -> Checked
8080
let mut all_vms = HashMap::new();
8181

0 commit comments

Comments
 (0)