Skip to content

Commit e1126fc

Browse files
committed
apply review
1 parent 800dcd4 commit e1126fc

File tree

2 files changed

+36
-24
lines changed

2 files changed

+36
-24
lines changed

crates/vm/src/stdlib/sys.rs

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1109,23 +1109,15 @@ mod sys {
11091109

11101110
#[pyfunction]
11111111
fn _settraceallthreads(tracefunc: PyObjectRef, vm: &VirtualMachine) {
1112-
let func = if vm.is_none(&tracefunc) {
1113-
None
1114-
} else {
1115-
Some(tracefunc.clone())
1116-
};
1112+
let func = (!vm.is_none(&tracefunc)).then(|| tracefunc.clone());
11171113
*vm.state.global_trace_func.lock() = func;
11181114
vm.trace_func.replace(tracefunc);
11191115
update_use_tracing(vm);
11201116
}
11211117

11221118
#[pyfunction]
11231119
fn _setprofileallthreads(profilefunc: PyObjectRef, vm: &VirtualMachine) {
1124-
let func = if vm.is_none(&profilefunc) {
1125-
None
1126-
} else {
1127-
Some(profilefunc.clone())
1128-
};
1120+
let func = (!vm.is_none(&profilefunc)).then(|| profilefunc.clone());
11291121
*vm.state.global_profile_func.lock() = func;
11301122
vm.profile_func.replace(profilefunc);
11311123
update_use_tracing(vm);

crates/vm/src/stdlib/thread.rs

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -617,24 +617,37 @@ pub(crate) mod _thread {
617617
impl Local {
618618
fn l_dict(&self, vm: &VirtualMachine) -> PyDictRef {
619619
let thread_id = std::thread::current().id();
620-
let mut data = self.inner.data.lock();
621620

622-
if let Some(dict) = data.get(&thread_id) {
623-
return dict.clone();
621+
// Fast path: check if dict exists under lock
622+
if let Some(dict) = self.inner.data.lock().get(&thread_id).cloned() {
623+
return dict;
624624
}
625625

626-
// Create new dict for this thread
627-
let dict = vm.ctx.new_dict();
628-
data.insert(thread_id, dict.clone());
626+
// Slow path: allocate dict outside lock to reduce lock hold time
627+
let new_dict = vm.ctx.new_dict();
629628

630-
// Register cleanup guard for this thread
631-
let guard = LocalGuard {
632-
local: std::sync::Arc::downgrade(&self.inner),
633-
thread_id,
629+
// Insert with double-check to handle races
630+
let mut data = self.inner.data.lock();
631+
use std::collections::hash_map::Entry;
632+
let (dict, need_guard) = match data.entry(thread_id) {
633+
Entry::Occupied(e) => (e.get().clone(), false),
634+
Entry::Vacant(e) => {
635+
e.insert(new_dict.clone());
636+
(new_dict, true)
637+
}
634638
};
635-
LOCAL_GUARDS.with(|guards| {
636-
guards.borrow_mut().push(guard);
637-
});
639+
drop(data); // Release lock before TLS access
640+
641+
// Register cleanup guard only if we inserted a new entry
642+
if need_guard {
643+
let guard = LocalGuard {
644+
local: std::sync::Arc::downgrade(&self.inner),
645+
thread_id,
646+
};
647+
LOCAL_GUARDS.with(|guards| {
648+
guards.borrow_mut().push(guard);
649+
});
650+
}
638651

639652
dict
640653
}
@@ -760,7 +773,14 @@ pub(crate) mod _thread {
760773

761774
#[pymethod]
762775
fn join(&self, timeout: OptionalArg<Option<f64>>, vm: &VirtualMachine) -> PyResult<()> {
763-
let _timeout_val = timeout.flatten().unwrap_or(-1.0);
776+
// Validate timeout: None or negative means wait forever, positive is not supported
777+
if let OptionalArg::Present(Some(t)) = timeout
778+
&& t > 0.0
779+
{
780+
return Err(vm.new_value_error(
781+
"timeout parameter is not supported for _ThreadHandle.join()".to_owned(),
782+
));
783+
}
764784

765785
// Check for self-join and if already joined
766786
let join_handle = {

0 commit comments

Comments
 (0)