[ESI] Yield gil before blocking operations in MessageDataFuture (#8789)

In case an ESI runtime backend uses some form of multi-threading, and a user has registered a Python callback with an ESI port, deadlock may occur when calling `MessageDataFuture` functions, due to calling a blocking operation while holding the GIL.

Instead, release the GIL while calling the blocking operations.
This commit is contained in:
Morten Borup Petersen 2025-07-28 19:39:46 +02:00 committed by GitHub
parent 9fe4c337fb
commit 29f4e1311e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 15 additions and 3 deletions

View File

@ -261,10 +261,22 @@ PYBIND11_MODULE(esiCppAccel, m) {
// emits an error.
return f.valid();
})
.def("wait", &std::future<MessageData>::wait)
.def("wait",
[](std::future<MessageData> &f) {
// Yield the GIL while waiting for the future to complete, in case
// of python callbacks occuring from other threads while waiting.
py::gil_scoped_release release{};
f.wait();
})
.def("get", [](std::future<MessageData> &f) {
MessageData data = f.get();
return py::bytearray((const char *)data.getBytes(), data.getSize());
std::optional<MessageData> data;
{
// Yield the GIL while waiting for the future to complete, in case of
// python callbacks occuring from other threads while waiting.
py::gil_scoped_release release{};
data.emplace(f.get());
}
return py::bytearray((const char *)data->getBytes(), data->getSize());
});
py::class_<ChannelPort>(m, "ChannelPort")