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.
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.