When the `client` argument is NULL, return a zero initialized
`pthread_t` object from `jack_client_thread_id()`. Returning
`-EINVAL` can be problematic because even though `pthread_t` is
a typedef for `unsigned long` in glibc, it is still a pointer,
not a numeric identifier. And in musl, it is a typedef to a
pointer, which results in a warning:
In file included from ../spa/include/spa/support/cpu.h:34,
from ../pipewire-jack/src/pipewire-jack.c:40:
../pipewire-jack/src/pipewire-jack.c: In function 'jack_client_thread_id':
../spa/include/spa/utils/defs.h:274:11: warning: returning 'int' from a function with return type 'jack_native_thread_t' {aka 'struct __pthread *'} makes pointer from integer without a cast [-Wint-conversion]
274 | return (val); \
| ^
../pipewire-jack/src/pipewire-jack.c:3775:2: note: in expansion of macro 'spa_return_val_if_fail'
3775 | spa_return_val_if_fail(c != NULL, -EINVAL);
For a JACK client, the context and node is the same. It makes sense to
also run the rules on the context properties so that application
name etc. can be matched as well.
Fixes#2580
Pass MIDI events as they are.
JACK requires NoteOn 0-velocity midi events to be patched to NoteOff
events for compatibility with LV2 plugins. Let's do this patchup in
the JACK layer then and add an option to disable it.
It's best to pass the midi messages unmodified and then patch them up
wherever they need patching up.
The client needs to be cleaned up properly, otherwise references
to its storage may remain, which can later result in use-after-frees.
For example, the via the various embedded `spa_hook`s in it.
See #2394
Check pointers before calling the destructors (where needed), so that
a not fully constructed `client` object may be passed to `jack_client_close()`.
Furthermore, remove the metadata proxy and object listeners as well.
Move the initialization of some of `client`'s members right after
allocation, so that it will be simpler to tear down the client object
even if `jack_client_open()` fails later.
Furthermore, initialize `client::driver_id` to `SPA_ID_INVALID`.
Fixes#1867, as this is the only u64 atomic access in the tree
All other accesses to pw_node_activation::sync_timeout are unprotected,
so they must assume lock ownership
When some blocking method is performed on the process thread, like
jack_connect() mark the data thread as blocked while we wait for the
thread loop to process the result.
If we then try to do a blocking _invoke from the thread loop on the
data thread, make sure we don't wait for it to complete or else we
deadlock.
Make all streams and filters handle PIPEWIRE_PROPS.
The order for applying stream/filter properties is:
1) application provided properties.
2) generic config.
3) match rules.
4) environment variables (PIPEWIRE_PROPS, ...) from generic to
more specific.
5) defaults.
Make helper method to parse thread properties and add 2 new properties
to control name and stack-size of the thread.
Use properties when creating threads with the default utils.
Use the default thread utils instead of pthread_create so that the
properties are used.
The alias is not a good property to sort on, it contains the object
path and could sort playback_11 before playback_2.
Just group ports of the same node together, then sort by port_id and if
that fails, use the serial number.
See #2260
Setting a global thread-utils is not a good idea, especially
when multiple contexts will register their own interface.
Instead, set the thread-utils as a context object and use this to
configure the data loop in the context.
In JACK we need a per context implementation of the interface so that
we can find the context specific thread-utils.
See #2252
Make a custom thread_utils that can use the configured global
thread creator and set this in the data-loop.
This ensure that the data loop uses the creator thread when activated.
See #1495
We are really interested in the error code of the statements we queued
before the sync so clear any previous error first. Otherwise we might
pick up a previous random error, which never gets cleared.
See #1714
If we do_sync from the data thread, release the rt_lock so that any
callbacks that may happen while waiting can grab the rt_lock.
We could also temporarily disable the rt_lock grabbing before the
callbacks.
In any case the callbacks will need to be called while we execute
the blocking function in the process callback.
Remove limit on max results from _get_ports() and _get_all_connections()
by using a dynamic array.
Keep the limit on the max number of midi inputs we can mix.
As soon as a JACK app is started, the automatic quantum change is
disabled. This means no pulse/alsa app can change the quantum.
The only way to change the quantum is with node.force-quantum or
with the settings metadata.
This means only a JACK buffersize change (usually controlled from the
JACK app, such as in ardour) or a metadata change (from the command
line) can modify things. Both of those are usually caused by a user
action.
For JACK apps where the quantum is allowed to change automatically,
explicit rules need to be placed in the config.
Add a node.force-quantum and node.force-rate property. When no global
quantum or rate is enforce with settings, the last updated node property
is used as the quantum.
Make jack use the force-quantum property when set_buffersize is used to
make sure that the quantum is not just a suggestion but a hard forced
one. This makes it possible for ardour or other jack apps to raise the
quantum above the max-quantum but also ensure that it will not change
by any other application (unless other jack apps).
Fixes#2079
We must use the serial for generating the uuid.
We use the serial for the port_id and jack_port_uuid_generate() can
be used to turn that into a uuid. So all mappings to and from
uuid need to be with serials.