MCPcopy Create free account
hub / github.com/pybind/pybind11 / test_scoped_critical_section2

Function test_scoped_critical_section2

tests/test_scoped_critical_section.cpp:102–178  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

100}
101
102void test_scoped_critical_section2(const py::handle &cls) {
103 auto barrier = std::barrier(3);
104 auto bool_wrapper1 = cls(false);
105 auto bool_wrapper2 = cls(false);
106 std::pair<bool, bool> output{false, false};
107
108 {
109 // Release the GIL to allow run threads in parallel.
110 py::gil_scoped_release gil_release{};
111
112 std::thread t1([&]() {
113 // Use gil_scoped_acquire to ensure we have a valid Python thread state
114 // before entering the critical section. Otherwise, the critical section
115 // will cause a segmentation fault.
116 py::gil_scoped_acquire ensure_tstate{};
117 // Enter the critical section with two different objects.
118 // This will ensure that the critical section is locked for both objects.
119 py::scoped_critical_section lock{bool_wrapper1, bool_wrapper2};
120 // At this point, objects are locked by this thread via the scoped_critical_section.
121 // This barrier will ensure that other threads wait until this thread has released
122 // the critical section before proceeding.
123 barrier.arrive_and_wait();
124 // Sleep for a short time to simulate some work in the critical section.
125 // This sleep is necessary to test the locking mechanism properly.
126 std::this_thread::sleep_for(std::chrono::milliseconds(10));
127 auto *bw1 = bool_wrapper1.cast<BoolWrapper *>();
128 auto *bw2 = bool_wrapper2.cast<BoolWrapper *>();
129 bw1->set(true);
130 bw2->set(true);
131 });
132
133 std::thread t2([&]() {
134 // This thread will wait until the first thread has entered the critical section due to
135 // the barrier.
136 barrier.arrive_and_wait();
137 {
138 // Use gil_scoped_acquire to ensure we have a valid Python thread state
139 // before entering the critical section. Otherwise, the critical section
140 // will cause a segmentation fault.
141 py::gil_scoped_acquire ensure_tstate{};
142 // Enter the critical section with the same object as the first thread.
143 py::scoped_critical_section lock{bool_wrapper1};
144 // At this point, the critical section is released by the first thread, the value
145 // is set to true.
146 auto *bw1 = bool_wrapper1.cast<BoolWrapper *>();
147 output.first = bw1->get();
148 }
149 });
150
151 std::thread t3([&]() {
152 // This thread will wait until the first thread has entered the critical section due to
153 // the barrier.
154 barrier.arrive_and_wait();
155 {
156 // Use gil_scoped_acquire to ensure we have a valid Python thread state
157 // before entering the critical section. Otherwise, the critical section
158 // will cause a segmentation fault.
159 py::gil_scoped_acquire ensure_tstate{};

Callers 1

TEST_SUBMODULEFunction · 0.70

Calls 3

setMethod · 0.45
getMethod · 0.45
joinMethod · 0.45

Tested by

no test coverage detected