> I think the way to properly handle GIL from long running calls
> is to add py::call_guard<py::gil_scoped_release>()
Josh
Full success! I snarfed the gr code for msg_queue, msg_handler, and message,
and added this call guard. There is no more GIL deadlock in the python OP25
apps.
Max
==============================================================================
tl;dr : following geek material may be safely skipped
Initial attempts to compile msg_handler OOT resulted in a compile error:
/usr/include/pybind11/detail/init.h:63:64: error: invalid new-_expression_ of abstract class type ‘gr::op25::msg_handler’
63 | inline Class *construct_or_initialize(Args &&...args) { return new Class{std::forward<Args>(args)...}; }
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /home/op25/repo/op25/src4/op25/gr-op25/python/op25/bindings/msg_handler_python.cc:26:
/home/op25/repo/op25/src4/op25/gr-op25/python/op25/bindings/../../../include/gnuradio/op25/msg_handler.h:27:16: note: because the following virtual functions are pure within ‘gr::op25::msg_handler’:
==============================================================================
In gr3.8 (swig) you get this error:
from gnuradio import gr
>>> h=gr.msg_handler()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.6/dist-packages/gnuradio/gr/runtime_swig.py", line 4629, in __init__
raise AttributeError("No constructor defined - class is abstract")
AttributeError: No constructor defined - class is abstract
==============================================================================
In gr3.10 (pybind11) with the in tree version of msg_handler you get
$ python3
Python 3.10.4 (main, Apr 2 2022, 09:04:19) [GCC 11.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from gnuradio import gr
>>> h=gr.msg_handler()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: gnuradio.gr.gr_python.msg_handler: No constructor defined!
>>>
==============================================================================
Eventually the OOT tree version was "fixed" after noticing that some of
the lines in the python bindings file in the in-tree version were commented:
// .def(py::init<>(),D(msg_handler,msg_handler,0))
// .def(py::init<gr::msg_handler const &>(), py::arg("arg0"),
// D(msg_handler,msg_handler,1)
// )
==============================================================================
py::call_guard<py::gil_scoped_release>()
Me of little faith, I wanted to ensure this would re-acquire the lock on
the way back from C++ to python. Yes, RAII style, its destructor makes sure
of that
if (active)
PyEval_RestoreThread(tstate);
==============================================================================
Finally, the following "gdb" command will identify the thread that holds(held)
the Python GIL:
p *(PyThreadState*)_PyRuntime.ceval.gil.last_holder._value
The "python3-dbg" and "libpython3-dbg" packages must be installed in order to
enable the gdb python extensions.
==============================================================================
Thanks Josh