Use a safer version of the before and after hooks. First call
all before hooks and save them in reverse order in a save list.
Then call the after event for the ones remaining in the save list
and move them back to the hook list.
This makes it possible to remove the hooks from one the callbacks or
even from other threads with the right locks. Found as a solution to
the following problem as observed in vlc:
main thread thread_loop
pw_thread_loop_lock() before hook: lock suspend thread
pw_context_destroy()
- removes before hook to flush clients
pw_thread_loop_unlock()
before hook: lock acquired, resume
before hook: flush client hook executed
*crash*
pw_thread_loop_stop()
pw_thread_loop_destroy()
Any of the safer cursor methods (like spa_hook_list_call()) would also
work but are more expensive and don't reverse the before/after
order.
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.
Timestamps have usec precision and the seconds are limited
to 9 digits. Usually what matters in these messages is to spot
delays between printouts and not really what is the absolute
time of the system.
FreeBSD doesn't provide timerfd and eventfd functions. These are implemented in
3rd party library called epoll-shim. Link targets requiring these functions to
this library.
When we do invoke from the loop thread, first process the pending
invoke items before handling ours. This can be used to sync the
invoke queue before cleanup.
Add system functions that can execute on the evenless Real-Time
subsystem. https://evlproject.org/
Enable this plugin as the system library for the data thread and
all poll/timerfd/eventfd will execute on the evl subsystem.
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.
Make a set-prop command to set a property from the config file
into a pw_properties. Pass this to the pw_core_new() and the
main-loop to tweak some stuff.
Move some warns to errors
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.