Add a struct spa_log_topic that allows for logical grouping of messages.
The new macros spa_log_logt() and spa_log_logtv() take a topic as
argument, the topic's level acts as filter.
A new macro spa_log_topic_init() initializes a topic. By default a topic
inherits its logger's debug level but a logger implementation may set
that topic to a specific fixed log level.
The various spa_log_*() macros transparently wrap new and old
implementations:
- if the implementation is version 0, the new logt() calls drop the
topic and get routed into the old log() calls
- if the implementation is version 1, the old log() calls use a NULL
topic and get routed into the new logt() calls
All spa_log_* macros use the SPA_LOG_DEFAULT_TOPIC topic (NULL), it is
up to the caller to redefine that. Alternatively, use spa_logt_* to pass
an explicit topic.
There is one crucial flaw in this implementation: log topics are
initialized to their target level by the current logger. Where a topic
is initialized but the logger is switched later, the topic is not
automatically re-initialized. Ultimately this shouldn't matter for
real-world use-cases.
spa_log_logv was missing, so with this ifdef'd out we already fail to
compile:
spa/plugins/alsa/alsa-acp-device.c:1003: undefined reference to `spa_log_logv'
And it appears that the only requirement is __VA_ARGS__ support in the
compiler which we require in other places anyway.
Several places in the code don't handle reconnecting DBus connections
yet. In those cases, a ref to the DBusConnection handle needs to be
kept, so that there's no use-after-free if it gets freed by spa_dbus
if the connection is broken.
Adjust spa_dbus so that others keeping additional refs is safe.
Add more info to the main SPA page and split the design vs plugin pages up,
together with some more documentation to ideally lower make this easier to
understand on a glance.
Most of the actual plugin loading documentation are unmodified.
Subdirectories buffer, control, debug, monitor, pod, support and utils, others
are still missing. Headers are grouped either per subdirectory (e.g. buffer/
gets added to group spa_buffer) or per-file (e.g. spa_json is a separate
group), whatever seemed like the most sensible approach.
Previously, the return value of `strrchr()` was not checked
in `spa_log_impl_logv()` which could cause a segmentation fault
in `snprintf()` if the `file` string argument does not contain
any directory separators ('/').
For example,
./build/spa/tools/spa-inspect ./build/spa/plugins/alsa/libspa-alsa.so
could run into this problem:
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7f1d505 in __strlen_avx2 () from /usr/lib/libc.so.6
(gdb) bt
#0 0x00007ffff7f1d505 in __strlen_avx2 () from /usr/lib/libc.so.6
#1 0x00007ffff7e29408 in __vfprintf_internal () from /usr/lib/libc.so.6
#2 0x00007ffff7e3a19a in __vsnprintf_internal () from /usr/lib/libc.so.6
#3 0x00007ffff7e146f6 in snprintf () from /usr/lib/libc.so.6
#4 0x0000555555558818 in spa_log_impl_logv (object=<optimized out>, level=SPA_LOG_LEVEL_INFO,
file=0x7fffffffd4d0 "[I][", line=260, func=0x7ffff7ce8090 "error_node", fmt=<optimized out>,
args=0x7fffffffd920) at ../spa/include/spa/support/log-impl.h:49
#5 0x00007ffff7d8c69e in alsa_error_handler (file=<optimized out>, line=<optimized out>,
function=<optimized out>, err=<optimized out>, fmt=<optimized out>)
at ../spa/plugins/alsa/acp/alsa-util.c:866
#6 0x00007ffff7cd6a8f in ?? () from /usr/lib/libasound.so.2
#7 0x00007ffff7cdb55e in snd_use_case_mgr_open () from /usr/lib/libasound.so.2
#8 0x00007ffff7d8940f in pa_alsa_ucm_query_profiles (ucm=ucm@entry=0x55555556ba28, card_index=0)
at ../spa/plugins/alsa/acp/alsa-ucm.c:752
#9 0x00007ffff7d6e3c2 in acp_card_new (index=0, props=props@entry=0x7fffffffdc50)
at ../spa/plugins/alsa/acp/acp.c:1508
#10 0x00007ffff7d29b7a in impl_init (factory=<optimized out>, handle=0x55555556b540,
info=<optimized out>, support=<optimized out>, n_support=<optimized out>)
at ../spa/plugins/alsa/alsa-acp-device.c:963
#11 0x0000555555558429 in inspect_factory (factory=0x7ffff7daefa0 <spa_alsa_acp_device_factory>,
data=0x7fffffffdcf0) at ../spa/tools/spa-inspect.c:231
#12 main (argc=<optimized out>, argv=<optimized out>) at ../spa/tools/spa-inspect.c:309
as in that particular case, the filename was returned by libasound,
and it was just "parser.c".
Furthermore, separate the static variable from the rest, and apply
the `const` qualifier to the pointers in the `levels` array.
Because the signal can't be removed from the callback we can
simply iterate backwards and then forwards.
The first added hook (the unlock/lock pair) is called last before
going into the poll and first when leaving. This executes all other
callbacks inside a locked situation. And removing them with the lock
is not going to cause problems.
This tool detects and fixes common English spelling mistakes, with
generally very few mistakes.
Here is the command I used to generate this commit. There were a few
changes that had to be done manually, and of course adding the ignore
file:
```shell
codespell -I .codespell-ignore -x .codespell-ignore -w
```
I didn’t add it to the CI, but this would be a good place for it.
This is more in line with wayland and it allows us to create new
interfaces in modules without having to add anything to the type
enum. It also removes some lookups to map type_id to readable
name in debug.
Define a set of standard factory names and document what they
contain. This makes it possible to change the implementation by
mapping the factory-name to a different shared library.
Move the epoll functions to the system functions and make the loop
use those. Use simple mask for events instead of enum.
Add the used system api in pw_loop.
Add System API to spa_support and use it where possible.
Pass the system API used in the realtime loops in spa_support as
well and use this in the realtime paths.
Improve bootstrapping, load only the log and cpu interfaces because
those can/need to be shared between instances. Let the core load
the other interfaces.
Add keys to configure the System and Loop implementations used in
pw_loop.
Make a new API to hide some the implementation of eventfd, timerfd
and signalfd along with clock and read/write/ioctl/close functions.
We would like to have plugins use the abstractions so that we
can switch them to something else when needed.
The interface struct has the type,version and methods of the
interface.
Make spa interfaces extend from spa_interface and make a
separate structure for the methods.
Pass a generic void* as the first argument of methods, like
we don in PipeWire.
Bundle the methods + implementation in a versioned inteface
and use that to invoke methods. This way we can do version
checks on the methods.
Make resource and proxy interfaces that we can can call. We
can then make the core interfaces independent on proxy/resource and
hide them in the lower layers.
Add add_listener method to methods of core interfaces, just
like SPA.
Remove the done and error callbacks. The error callback is in an
error message. The done callback is replace with spa_pending.
Make enum_params take a callback and data for the results. This allows
us to push the results one after another to the app and avoids ownership
issues of the passed data. We can then extend this to handle the async
case by doing a _wait call with a spa_pending+callback+data that will
be called when the _enum_params returns and async result.
Add a sync method.
All methods can now return SPA_RESULT_IS_ASYNC return values and you
can use spa_node_wait() to register a callback when they complete
with optional extra parameters. This makes it easier to sync and
handle the reply.
Make helper methods to simulate the sync enum_params behaviour for
sync nodes.
Let the transport generate the sequence number for pw_resource_sync()
and pw_proxy_sync(). That way we don't need to keep track of numbers
ourselves and we can match the reply to the request easily.