@@ -30,23 +30,31 @@ void test_scoped_critical_section(const py::handle &cls) {
30
30
auto bool_wrapper = cls (false );
31
31
bool output = false ;
32
32
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
+ }
50
58
51
59
if (!output) {
52
60
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) {
59
67
auto bool_wrapper2 = cls (false );
60
68
std::pair<bool , bool > output{false , false };
61
69
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
+ }
89
108
90
109
if (!output.first || !output.second ) {
91
110
throw std::runtime_error (
@@ -98,23 +117,31 @@ void test_scoped_critical_section2_same_object_no_deadlock(const py::handle &cls
98
117
auto bool_wrapper = cls (false );
99
118
bool output = false ;
100
119
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
+ }
118
145
119
146
if (!output) {
120
147
throw std::runtime_error (
0 commit comments