Skip to content

Commit 74f5050

Browse files
committed
add two more tests
1 parent 7223e4f commit 74f5050

File tree

1 file changed

+77
-0
lines changed

1 file changed

+77
-0
lines changed

src/sync.rs

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1441,6 +1441,36 @@ mod tests {
14411441
});
14421442
}
14431443

1444+
#[cfg(not(target_arch = "wasm32"))] // We are building wasm Python with pthreads disabled
1445+
#[test]
1446+
fn test_critical_section_mutex2_same_object_no_deadlock() {
1447+
let barrier = Barrier::new(2);
1448+
1449+
let m = PyMutex::new(false);
1450+
1451+
std::thread::scope(|s| {
1452+
s.spawn(|| {
1453+
Python::attach(|py| {
1454+
with_critical_section_mutex2(py, &m, &m, |b1, b2| {
1455+
barrier.wait();
1456+
std::thread::sleep(std::time::Duration::from_millis(10));
1457+
unsafe { (*b1.get()) = true };
1458+
assert!(unsafe { *b2.get() });
1459+
});
1460+
});
1461+
});
1462+
s.spawn(|| {
1463+
barrier.wait();
1464+
Python::attach(|py| {
1465+
// this blocks until the other thread's critical section finishes
1466+
with_critical_section_mutex(py, &m, |b| {
1467+
assert!(unsafe { *b.get() });
1468+
});
1469+
});
1470+
});
1471+
});
1472+
}
1473+
14441474
#[cfg(feature = "macros")]
14451475
#[cfg(not(target_arch = "wasm32"))] // We are building wasm Python with pthreads disabled
14461476
#[test]
@@ -1496,6 +1526,53 @@ mod tests {
14961526
});
14971527
}
14981528

1529+
#[cfg(not(target_arch = "wasm32"))] // We are building wasm Python with pthreads disabled
1530+
#[test]
1531+
fn test_critical_section_mutex2_two_containers() {
1532+
let (m1, m2) = (PyMutex::new(vec![1, 2, 3]), PyMutex::new(vec![4, 5]));
1533+
1534+
std::thread::scope(|s| {
1535+
s.spawn(|| {
1536+
Python::attach(|py| {
1537+
with_critical_section_mutex2(py, &m1, &m2, |v1, v2| {
1538+
// v1.extend(v1)
1539+
let vec1 = unsafe { &mut *v1.get() };
1540+
let vec2 = unsafe { &*v2.get() };
1541+
vec1.extend(vec2.iter());
1542+
})
1543+
});
1544+
});
1545+
s.spawn(|| {
1546+
Python::attach(|py| {
1547+
with_critical_section_mutex2(py, &m1, &m2, |v1, v2| {
1548+
// v2.extend(v1)
1549+
let vec1 = unsafe { &*v1.get() };
1550+
let vec2 = unsafe { &mut *v2.get() };
1551+
vec2.extend(vec1.iter());
1552+
})
1553+
});
1554+
});
1555+
});
1556+
1557+
// execution order is not guaranteed, so we need to check both
1558+
// NB: extend should be atomic, items must not be interleaved
1559+
// v1.extend(v2)
1560+
// v2.extend(v1)
1561+
let expected1_vec1 = vec![1, 2, 3, 4, 5];
1562+
let expected1_vec2 = vec![4, 5, 1, 2, 3, 4, 5];
1563+
// v2.extend(v1)
1564+
// v1.extend(v2)
1565+
let expected2_vec1 = vec![1, 2, 3, 4, 5, 1, 2, 3];
1566+
let expected2_vec2 = vec![4, 5, 1, 2, 3];
1567+
1568+
let v1 = m1.lock().unwrap();
1569+
let v2 = m2.lock().unwrap();
1570+
assert!(
1571+
((*v1).eq(&expected1_vec1) && (*v2).eq(&expected1_vec2))
1572+
|| ((*v1).eq(&expected2_vec1) && (*v2).eq(&expected2_vec2))
1573+
);
1574+
}
1575+
14991576
#[test]
15001577
#[cfg(not(target_arch = "wasm32"))] // We are building wasm Python with pthreads disabled
15011578
fn test_once_ext() {

0 commit comments

Comments
 (0)