[Jack-Devel] Non-blocking I/O in process callback

Robin Gareus robin at gareus.org
Mon Nov 30 15:30:06 CET 2015

On 11/30/2015 03:00 PM, Xavier Mendez wrote:
> El 30/11/15 a les 14:27, Robin Gareus ha escrit:
>> On 11/30/2015 12:11 PM, Xavier Mendez wrote:
>>> Hello,
>>> I'm wondering whether it's safe to do non-blocking reads or writes from
>>> inside the process callback.
>>>  From what I've seen, non-blocking I/O doesn't cause the process to go
>>> into blocked state, and the realtime scheduler should not switch to
>>> another process. But the documentation doesn't seem to allow them:
>>>> [...] it cannot call functions that might block for a long time. This
>>>> includes all I/O functions (disk, TTY, network), [...]
>>> So, is it safe to use non-blocking I/O in the process callback?
>> On which platform?
> This is going to run on UNIX-like systems, mostly Linux, and I'm
> programming in C/C++.
>> The short answer is:
>>    "If you don’t know how long it will take, don't do it." [1]
>> All i/o involve syscalls, and then it depends what the kernel does for
>> the specific system call(s). Asynchronous I/O usually involves signals
>> at some point which makes it not safe to use.
> I wasn't very specific, let me clarify: I'm only going to do some
> read(2) or write(2) syscalls on an FD which has O_NONBLOCK set.
> AFAIK these don't involve signals...

I'm pretty sure they do in the current Linux kernel. There'll be an IRQ
once the read is complete.

>> Some implementation also
>> involve mutexes to avoid resource conflicts. You'll have to check the
>> standard-lib and kernel source for the system that you target.
> Hmm... Are mutexes a problem if the FD is used exclusively from the
> process callback?

How can you know that no other process is using the same file?

I have not checked the underlying implementation, but I can easily
imagine that there are locks in the kernel.

>> All moot anyway. Proper software needs to do error-handling and doing
>> that in a rt-callback is out of the question. So you need a non-realtime
>> thread anyway and if you have that you can directly do i/o there.
> Error handling is not a problem here, if those syscalls fail I'll simply
> deactivate the JACK client.
>> anyway, using a ringbuffer to decouple i/o is trivial: e.g.
>> https://github.com/jackaudio/example-clients/blob/master/capture_client.c
> Thanks for the advice, I'm currently using ringbuffers + worker threads
> but being able to do this I/O directly in process() would simplify the
> code considerably. I'll consider it, though.

Keep jack freewheeling in mind. When freewheeling the process callback
needs to wait for i/o to complete.

"worker thread" sounds like LV2. In this case you're good already since
the LV2 worker takes care of this.

On a different note: check async i/o performance first. Paul may chime
in later, I recall that he benchmarked single-threaded, thread-polls and
async i/o for Ardour at some point and opted for the first.

> Thank you for your help,
> Xavi
>> best,
>> robin
>> [1]
>> http://www.rossbencina.com/code/real-time-audio-programming-101-time-waits-for-nothing

More information about the Jackaudio mailing list