mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-25 06:35:12 +00:00
demo race when using call_guard<gil_scoped_release> and implicitly_convertible
This commit is contained in:
parent
028812ae7e
commit
5f3d8d806a
@ -97,5 +97,31 @@ TEST_SUBMODULE(call_policies, m) {
|
||||
|
||||
m.def("with_gil", report_gil_status);
|
||||
m.def("without_gil", report_gil_status, py::call_guard<py::gil_scoped_release>());
|
||||
|
||||
class MyInt {
|
||||
public:
|
||||
MyInt(int i)
|
||||
: i_(i)
|
||||
{}
|
||||
|
||||
int i_;
|
||||
};
|
||||
py::class_<MyInt>(m, "MyInt")
|
||||
.def(py::init<int>());
|
||||
py::implicitly_convertible<int, MyInt>();
|
||||
|
||||
// This function races
|
||||
m.def("guard_without_gil_implicit_conversion",
|
||||
[](MyInt my_int) {
|
||||
return my_int.i_;
|
||||
},
|
||||
py::call_guard<py::gil_scoped_release>());
|
||||
|
||||
// This function works fine
|
||||
m.def("without_gil_implicit_conversion",
|
||||
[](MyInt my_int) {
|
||||
py::gil_scoped_release gil_release;
|
||||
return my_int.i_;
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import pytest
|
||||
import threading
|
||||
|
||||
import env # noqa: F401
|
||||
|
||||
@ -217,3 +218,33 @@ def test_call_guard():
|
||||
if hasattr(m, "with_gil"):
|
||||
assert m.with_gil() == "GIL held"
|
||||
assert m.without_gil() == "GIL released"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"test_func",
|
||||
["guard_without_gil_implicit_conversion", "without_gil_implicit_conversion"],
|
||||
)
|
||||
def test_without_gil_implicit_conversion(test_func):
|
||||
try:
|
||||
func = getattr(m, test_func)
|
||||
except AttributeError:
|
||||
return
|
||||
|
||||
num_threads = 16
|
||||
|
||||
def check(results, i):
|
||||
results[i] = func(42) == 42
|
||||
|
||||
results = [None] * num_threads
|
||||
for _ in range(int(1e4)):
|
||||
threads = []
|
||||
for i in range(num_threads):
|
||||
thread = threading.Thread(target=check, args=(results, i))
|
||||
thread.start()
|
||||
threads.append(thread)
|
||||
for thread in threads:
|
||||
thread.join()
|
||||
|
||||
ok = all(results)
|
||||
if not ok:
|
||||
raise AssertionError(results)
|
||||
|
Loading…
Reference in New Issue
Block a user