spatialaudio / jackclient-python

🂻 JACK Audio Connection Kit (JACK) Client for Python :snake:
https://jackclient-python.readthedocs.io/
MIT License
132 stars 26 forks source link

"timeout waiting for client" from jack daemon when using libjack calls from within port_registration_callback #30

Closed mk-fg closed 8 years ago

mk-fg commented 8 years ago

Recently had an issue, where:

And that caused client (current git master - c5982a39) to reliably crash with:

cannot read result for request type 10 from server (Connection reset by peer)
cannot send event response to engine (Broken pipe)
cannot continue execution of the processing graph (Bad file descriptor)
jack_client_thread: graph error - exiting from JACK

And JACK1 (0.124.1, Debian Jessie) logging something like:

Oct 11 06:43:42 Paging-Test6 jackd1-paging[801]: timeout waiting for client paging.812 to handle a port registered event
Oct 11 06:43:42 Paging-Test6 jackd1-paging[801]: cannot send port registration notification to paging.812 (No such file or directory)

This seem to be 100% reproducible in these kinda-specific conditions - i.e. when it's same port name being registered for the second time during client lifetime - no other calls to that callback seem to trigger it. Can be easily reproduced with that particular app (before it was fixed not to call stuff from callbacks) by running alsa_out, closing it, then running it again - client drops with above symptoms.

Also, all connect() / disconnect() calls from within that callback seem to raise JackError, while actually creating/removing connections, for any ports.

So I wonder, is it expected (e.g. "calling stuff from callbacks is obviously bad!") or sensible behavior?

And if it is, maybe it should be documented under set_port_registration_callback? I.e. something like "calling other libjack functions here may lead to unexpected behavior like deadlocks or client timeouts" there. If so, I can probably create a PR, but given relative lack of JACK/client knowledge, I suspect I might not be best at describing what exactly should be avoided here.

mgeier commented 8 years ago

Thanks for the report. I'm not a JACK expert myself, I just took the documentation from the comments in the JACK header files and moved them to the Python docstrings, I hardly added anything myself.

Basically, I only know what's in the documentation. For the case of set_port_registration_callback(), it only says that "... the supplied function does not need to be suitable for real-time execution". It doesn't say if it is allowed to call other JACK API functions from there. But it says that the callback is called from a separate thread, so maybe this is the problem?

I'm not surprised that connect()/disconnect() doesn't work, because this would call the same callback again while it's still running, probably leading to some unexpected behavior (but I actually don't know if that's really the problem).

I think it would be best to ask this the JACK developers, perhaps on their mailing list: http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org

It would also be helpful if you could reduce your error case to a few lines of Python code without calling into this other module.

And if it is, maybe it should be documented under set_port_registration_callback?

Sure, as soon as you get confirmation from the JACK developers, I'd be happy to get a PR.

mk-fg commented 8 years ago

Right, guess I'll make a smaller proof of concept and try posting it to JACK's ML, then get back here.

Kinda hoped that you might confirm that it's something known and obvious, just maybe not well-documented in this module.

mk-fg commented 8 years ago

Posted the question to ML as suggested here: http://thread.gmane.org/gmane.comp.audio.jackit/29271

mk-fg commented 8 years ago

Got clarification from Paul Davis that it is indeed expected behavior - http://thread.gmane.org/gmane.comp.audio.jackit/29271/focus=29273 - but not documented there either, sadly.

Will make PR for the docs here shortly.