This commit is contained in:
Mana 2024-09-20 23:44:48 -07:00 committed by GitHub
commit a07e39e0f3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 57 additions and 0 deletions

View File

@ -109,5 +109,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
}

View File

@ -1,6 +1,7 @@
from __future__ import annotations
import pytest
import threading
import env # noqa: F401
from pybind11_tests import ConstructorStats
@ -247,3 +248,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)