Make a real debug context with a log function and move it to a new file.
This way we don't need to redefine a macro.
Make a new context for debugging to a log file. Make new functions to
debug to a log file.
Move the stringbuffer to string utils.
Integrate file/line/func and topics into the debug log.
We can remove some more things from the pipewire log_object function and
also add support for topics.
The pulse API uses either the node.name or object.serials so pass this
along in the TARGET_OBJECT instead of the NODE_TARGET now that
wireplumber handles this.
When we start the drain, we unpause the stream. When we conplete the
drain, we unpause again, which does nothing when the stream was already
unpaused. However, this leaves the drained state on the stream and so
the stream will never be able to play new data.
Trigger a new pw_stream_set_active() with the current stream state to
clear the drained state.
Fixes#2928
Add a new config section that can contain a set of commands to run after
starting.
There is only load-module available now but it can be used to remove the
dependency on pactl when starting the server.
Only enable pulse.idle.timeout for selected applications
(speech-dispatcher) and let other applications be. We can also
lower the minreq and min-quantum of speech-dispatcher now.
Fixes#2880
We don't need to pass the client to the module create and load
functions, they can work without a client.
The only place the client is used is to access the properties to make a
new connection to pipewire. This is also however not a good idea, we
should simply use the defaults used by the context or else a client
could set strange properties like remote.name etc for these internal
connections.
Also removing the dependency of the client will make it possible to load
modules from the startup script or other modules later.
When a client is not sending any data when it should be and causes an
underrun, mark it as idle and record the timestamp.
When a client is idle for pulse.idle.timeout seconds, set the stream
as inactive. When more data is received, set it back to active.
Add a pulse.idle.timeout option to set a global server default or
a per-stream value. Set the server default to 5 seconds. A value of 0
can be used to disable this feature.
With this change, badly behaving clients that are not sending any data
will be paused so that the sinks can suspend to save battery power.
Fixes#2839
Make a method to pause and resume a stream and keep track of the paused
state of the stream. Use this function instead of setting the stream
inactive/active so that we get nice logging for each state change.
When no maxlength is given, we use the MAXLENGTH value but we need to
round it DOWN (instead of up) because our buffer is only MAXLENGTH big.
Use CLAMP where we can.
When in capture mode, the maxlength exceeds MAXLENGTH, scale down the
fragsize instead.
Fixes noise in audacious when playing 6 channels sounds. float32 * 6
channels with the maximum buffer size would result in the ringbuffer
being overwritten.
Reducing the latency is just papering over the issue in #2702. The
real fix is to limit the blocksize to the fragsize like what is done
in 00a234daf2
Reducing the latency then also causes regressions like #2715 so don't
do that anymore.
Fixes#2715
Move the latency fraction calculation to fix_ functions so that the
new latency rate can be used when creating the streams.
Actually set the requested record attributes on the stream instead
of modifying the defaults.
See #2671
PulseAudio configures half of the fragsize as the source latency. It
also sends chunks as soon as they become available.
This means that we also need to configure the source with half of
the fragsize latency and send in chunks of fragsize/2. Keep this in
the unused (for record) minreq field.
The default metadata update may be delayed for some time after
SET_DEFAULT, since the session manager has to work on it.
MOVE_* commands need to know what the client thinks is the current
default sink, so that they can decide between "move to default" and
"move to specific device".
To avoid race condition here, stash the default value set by the client
and use it in the MOVE_* commands, until the metadata update arrives.
`client_update_quirks()` may modify `client::props` depending
on the "pulse.rules" section defined in the configuration file,
which means that it can change the value corresponding to the
"application.name" key. Therefore, `client::name` needs to
be queried after that.
`client::name` points to a string that is owned by `client::props`,
so when the property list is updated, it needs to be refreshed as well.
Otherwise, various use-after-frees can be triggered, for example:
==1471586==ERROR: AddressSanitizer: heap-use-after-free on address 0x60200007e7d0 at pc 0x7f14390755d0 bp 0x7ffe23edee30 sp 0x7ffe23ede5a8
READ of size 3 at 0x60200007e7d0 thread T0
#0 0x7f14390755cf in printf_common /usr/src/debug/gcc/libsanitizer/sanitizer_common/sanitizer_common_interceptors_format.inc:553
#1 0x7f1439077215 in __interceptor_vsnprintf /usr/src/debug/gcc/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:1665
#2 0x7f1434ead47d in spa_vscnprintf ../spa/include/spa/utils/string.h:239
#3 0x7f1434eae2ae in impl_log_logtv ../spa/plugins/support/logger.c:138
#4 0x7f14385cacc7 in pw_log_logt ../src/pipewire/log.c:135
#5 0x7f1433aef8e9 in do_set_profile ../src/modules/module-protocol-pulse/pulse-server.c:4656
#6 0x7f1433b0af4d in handle_packet ../src/modules/module-protocol-pulse/server.c:109
#7 0x7f1433b0e747 in do_read ../src/modules/module-protocol-pulse/server.c:276
#8 0x7f1433b0eb04 in on_client_data ../src/modules/module-protocol-pulse/server.c:306
#9 0x7f1434ec56a0 in source_io_func ../spa/plugins/support/loop.c:442
#10 0x7f1434ec4a21 in loop_iterate ../spa/plugins/support/loop.c:430
#11 0x7f14385dc23d in pw_main_loop_run ../src/pipewire/main-loop.c:148
#12 0x55b065d73722 in main ../src/daemon/pipewire.c:131
#13 0x7f143742928f (/usr/lib/libc.so.6+0x2928f)
#14 0x7f1437429349 in __libc_start_main (/usr/lib/libc.so.6+0x29349)
#15 0x55b065d722a4 in _start (./src/daemon/pipewire-pulse+0x42a4)
0x60200007e7d0 is located 0 bytes inside of 16-byte region [0x60200007e7d0,0x60200007e7e0)
freed by thread T0 here:
#0 0x7f14390be672 in __interceptor_free /usr/src/debug/gcc/libsanitizer/asan/asan_malloc_linux.cpp:52
#1 0x7f14386a775a in do_replace ../src/pipewire/properties.c:414
#2 0x7f14386a785e in pw_properties_set ../src/pipewire/properties.c:441
#3 0x7f14386a658b in pw_properties_update ../src/pipewire/properties.c:309
#4 0x7f1433adb055 in do_update_proplist ../src/modules/module-protocol-pulse/pulse-server.c:3246
#5 0x7f1433b0af4d in handle_packet ../src/modules/module-protocol-pulse/server.c:109
#6 0x7f1433b0e747 in do_read ../src/modules/module-protocol-pulse/server.c:276
#7 0x7f1433b0eb04 in on_client_data ../src/modules/module-protocol-pulse/server.c:306
#8 0x7f1434ec56a0 in source_io_func ../spa/plugins/support/loop.c:442
#9 0x7f1434ec4a21 in loop_iterate ../spa/plugins/support/loop.c:430
#10 0x7f14385dc23d in pw_main_loop_run ../src/pipewire/main-loop.c:148
#11 0x55b065d73722 in main ../src/daemon/pipewire.c:131
#12 0x7f143742928f (/usr/lib/libc.so.6+0x2928f)
previously allocated by thread T0 here:
#0 0x7f1439072faa in __interceptor_strdup /usr/src/debug/gcc/libsanitizer/asan/asan_interceptors.cpp:439
#1 0x7f14386a6fe2 in do_replace ../src/pipewire/properties.c:394
#2 0x7f14386a785e in pw_properties_set ../src/pipewire/properties.c:441
#3 0x7f1433a6c52d in read_props ../src/modules/module-protocol-pulse/message.c:147
#4 0x7f1433a6f467 in message_get ../src/modules/module-protocol-pulse/message.c:359
#5 0x7f1433ab3191 in do_set_client_name ../src/modules/module-protocol-pulse/pulse-server.c:1030
#6 0x7f1433b0af4d in handle_packet ../src/modules/module-protocol-pulse/server.c:109
#7 0x7f1433b0e747 in do_read ../src/modules/module-protocol-pulse/server.c:276
#8 0x7f1433b0eb04 in on_client_data ../src/modules/module-protocol-pulse/server.c:306
#9 0x7f1434ec56a0 in source_io_func ../spa/plugins/support/loop.c:442
#10 0x7f1434ec4a21 in loop_iterate ../spa/plugins/support/loop.c:430
#11 0x7f14385dc23d in pw_main_loop_run ../src/pipewire/main-loop.c:148
#12 0x55b065d73722 in main ../src/daemon/pipewire.c:131
#13 0x7f143742928f (/usr/lib/libc.so.6+0x2928f)
Add some 'before' debug info of the attributes.
First clamp the fragsize to the maxlength and then clamp to the
minfrag or else we could bypass the configured minfrag by setting a
lower maxlength.
Scale the maxlength to at least twice the fragsize so that we can
buffer enough data in the ringbuffer to serve fragsize bytes.
See #2447
Store a pointer to the owner `impl` object instead of
the (embedded) `stat` object. This way `message_free()`
can be simplified since the owner `impl` does not need
to be passed explicitly.
The `impl::servers` list contains all servers, and they are all
destroyed in `impl_clear()`. However, by that time, modules were
not freed previously, so if there were any instances of
*module-protocol-native-tcp* loaded, then the unload() method
of those would call `server_free()` on already freed servers,
resulting in use-after-frees. Fix that by unloading modules
before destroying the servers.
==451490==ERROR: AddressSanitizer: heap-use-after-free on address 0x612000006050 ...
READ of size 8 at 0x612000006050 thread T0
#0 0x7f45edb19a0c in server_free ../src/modules/module-protocol-pulse/server.c:1022
#1 0x7f45edb46c7d in module_native_protocol_tcp_unload ../src/modules/module-protocol-pulse/modules/module-native-protocol-tcp.c:66
#2 0x7f45eda893c7 in module_unload ../src/modules/module-protocol-pulse/module.c:128
#3 0x7f45edaf7269 in impl_unload_module ../src/modules/module-protocol-pulse/pulse-server.c:5336
#4 0x7f45edaa1583 in pw_map_for_each ../src/pipewire/map.h:238
#5 0x7f45edaf79c5 in impl_clear ../src/modules/module-protocol-pulse/pulse-server.c:5358
...
0x612000006050 is located 16 bytes inside of 264-byte region [0x612000006040,0x612000006148)
freed by thread T0 here:
#0 0x7f45f30be672 in __interceptor_free /usr/src/debug/gcc/libsanitizer/asan/asan_malloc_linux.cpp:52
#1 0x7f45edb1a48a in server_free ../src/modules/module-protocol-pulse/server.c:1040
#2 0x7f45edaf730b in impl_clear ../src/modules/module-protocol-pulse/pulse-server.c:5347
...
Fixes: f181210b29 ("pulse-server: properly unload modules")