Skip to content

Commit d6084c0

Browse files
committed
fix: fix test critical_section
1 parent f14b2ce commit d6084c0

File tree

2 files changed

+88
-62
lines changed

2 files changed

+88
-62
lines changed

.github/workflows/ci.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ env:
2020
PIP_ONLY_BINARY: numpy
2121
FORCE_COLOR: 3
2222
PYTEST_TIMEOUT: 300
23-
PYTEST_ADDOPTS: "-k critical_section"
2423
# For cmake:
2524
VERBOSE: 1
2625
CMAKE_COLOR_DIAGNOSTICS: 1

tests/test_scoped_critical_section.cpp

Lines changed: 88 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -30,23 +30,31 @@ void test_scoped_critical_section(const py::handle &cls) {
3030
auto bool_wrapper = cls(false);
3131
bool output = false;
3232

33-
std::thread t1([&]() {
34-
py::scoped_critical_section lock{bool_wrapper};
35-
barrier.arrive_and_wait();
36-
auto *bw = bool_wrapper.cast<BoolWrapper *>();
37-
std::this_thread::sleep_for(std::chrono::milliseconds(10));
38-
bw->set(true);
39-
});
40-
41-
std::thread t2([&]() {
42-
barrier.arrive_and_wait();
43-
py::scoped_critical_section lock{bool_wrapper};
44-
auto *bw = bool_wrapper.cast<BoolWrapper *>();
45-
output = bw->get();
46-
});
47-
48-
t1.join();
49-
t2.join();
33+
{
34+
py::gil_scoped_release gil_release{};
35+
36+
std::thread t1([&]() {
37+
py::gil_scoped_acquire ensure_tstate{};
38+
py::scoped_critical_section lock{bool_wrapper};
39+
barrier.arrive_and_wait();
40+
auto *bw = bool_wrapper.cast<BoolWrapper *>();
41+
std::this_thread::sleep_for(std::chrono::milliseconds(10));
42+
bw->set(true);
43+
});
44+
45+
std::thread t2([&]() {
46+
barrier.arrive_and_wait();
47+
{
48+
py::gil_scoped_acquire ensure_tstate{};
49+
py::scoped_critical_section lock{bool_wrapper};
50+
auto *bw = bool_wrapper.cast<BoolWrapper *>();
51+
output = bw->get();
52+
}
53+
});
54+
55+
t1.join();
56+
t2.join();
57+
}
5058

5159
if (!output) {
5260
throw std::runtime_error("Scoped critical section test failed: output is false");
@@ -59,33 +67,44 @@ void test_scoped_critical_section2(const py::handle &cls) {
5967
auto bool_wrapper2 = cls(false);
6068
std::pair<bool, bool> output{false, false};
6169

62-
std::thread t1([&]() {
63-
py::scoped_critical_section lock{bool_wrapper1, bool_wrapper2};
64-
barrier.arrive_and_wait();
65-
std::this_thread::sleep_for(std::chrono::milliseconds(10));
66-
auto *bw1 = bool_wrapper1.cast<BoolWrapper *>();
67-
auto *bw2 = bool_wrapper2.cast<BoolWrapper *>();
68-
bw1->set(true);
69-
bw2->set(true);
70-
});
71-
72-
std::thread t2([&]() {
73-
barrier.arrive_and_wait();
74-
py::scoped_critical_section lock{bool_wrapper1};
75-
auto *bw1 = bool_wrapper1.cast<BoolWrapper *>();
76-
output.first = bw1->get();
77-
});
78-
79-
std::thread t3([&]() {
80-
barrier.arrive_and_wait();
81-
py::scoped_critical_section lock{bool_wrapper2};
82-
auto *bw2 = bool_wrapper2.cast<BoolWrapper *>();
83-
output.second = bw2->get();
84-
});
85-
86-
t1.join();
87-
t2.join();
88-
t3.join();
70+
{
71+
py::gil_scoped_release gil_release{};
72+
73+
std::thread t1([&]() {
74+
py::gil_scoped_acquire ensure_tstate{};
75+
py::scoped_critical_section lock{bool_wrapper1, bool_wrapper2};
76+
barrier.arrive_and_wait();
77+
std::this_thread::sleep_for(std::chrono::milliseconds(10));
78+
auto *bw1 = bool_wrapper1.cast<BoolWrapper *>();
79+
auto *bw2 = bool_wrapper2.cast<BoolWrapper *>();
80+
bw1->set(true);
81+
bw2->set(true);
82+
});
83+
84+
std::thread t2([&]() {
85+
barrier.arrive_and_wait();
86+
{
87+
py::gil_scoped_acquire ensure_tstate{};
88+
py::scoped_critical_section lock{bool_wrapper1};
89+
auto *bw1 = bool_wrapper1.cast<BoolWrapper *>();
90+
output.first = bw1->get();
91+
}
92+
});
93+
94+
std::thread t3([&]() {
95+
barrier.arrive_and_wait();
96+
{
97+
py::gil_scoped_acquire ensure_tstate{};
98+
py::scoped_critical_section lock{bool_wrapper2};
99+
auto *bw2 = bool_wrapper2.cast<BoolWrapper *>();
100+
output.second = bw2->get();
101+
}
102+
});
103+
104+
t1.join();
105+
t2.join();
106+
t3.join();
107+
}
89108

90109
if (!output.first || !output.second) {
91110
throw std::runtime_error(
@@ -98,23 +117,31 @@ void test_scoped_critical_section2_same_object_no_deadlock(const py::handle &cls
98117
auto bool_wrapper = cls(false);
99118
bool output = false;
100119

101-
std::thread t1([&]() {
102-
py::scoped_critical_section lock{bool_wrapper, bool_wrapper};
103-
barrier.arrive_and_wait();
104-
std::this_thread::sleep_for(std::chrono::milliseconds(10));
105-
auto *bw = bool_wrapper.cast<BoolWrapper *>();
106-
bw->set(true);
107-
});
108-
109-
std::thread t2([&]() {
110-
barrier.arrive_and_wait();
111-
py::scoped_critical_section lock{bool_wrapper};
112-
auto *bw = bool_wrapper.cast<BoolWrapper *>();
113-
output = bw->get();
114-
});
115-
116-
t1.join();
117-
t2.join();
120+
{
121+
py::gil_scoped_release gil_release{};
122+
123+
std::thread t1([&]() {
124+
py::gil_scoped_acquire ensure_tstate{};
125+
py::scoped_critical_section lock{bool_wrapper, bool_wrapper};
126+
barrier.arrive_and_wait();
127+
std::this_thread::sleep_for(std::chrono::milliseconds(10));
128+
auto *bw = bool_wrapper.cast<BoolWrapper *>();
129+
bw->set(true);
130+
});
131+
132+
std::thread t2([&]() {
133+
barrier.arrive_and_wait();
134+
{
135+
py::gil_scoped_acquire ensure_tstate{};
136+
py::scoped_critical_section lock{bool_wrapper};
137+
auto *bw = bool_wrapper.cast<BoolWrapper *>();
138+
output = bw->get();
139+
}
140+
});
141+
142+
t1.join();
143+
t2.join();
144+
}
118145

119146
if (!output) {
120147
throw std::runtime_error(

0 commit comments

Comments
 (0)