Add an option to export the node from the factory.
That way you can locally create a node from a factory and then export it
to the server. This is handy to make object in the server from a config
file using the node-factory.
See !1643
Previously, the resource listener was not removed when
the `node_data` object was freed, which could lead to
a use-after-free when the resource emitted an event
later.
==2787072==ERROR: AddressSanitizer: heap-use-after-free on address 0x61d000016728 at pc 0x7ffff7175b52 bp 0x7fffffffb930 sp 0x7fffffffb920
WRITE of size 8 at 0x61d000016728 thread T0
#0 0x7ffff7175b51 in spa_list_remove ../spa/include/spa/utils/list.h:77
#1 0x7ffff717cb5a in pw_resource_destroy ../src/pipewire/resource.c:335
#2 0x7ffff7051c56 in pw_global_destroy ../src/pipewire/global.c:417
#3 0x7ffff6f82a68 in registry_destroy ../src/pipewire/impl-core.c:130
#4 0x7ffff3a5f349 in registry_demarshal_destroy ../src/modules/module-protocol-native/protocol-native.c:784
#5 0x7ffff3a2c9ed in process_messages ../src/modules/module-protocol-native.c:352
#6 0x7ffff3a2e2ea in connection_data ../src/modules/module-protocol-native.c:423
#7 0x7ffff3e09402 in source_io_func ../spa/plugins/support/loop.c:427
#8 0x7ffff3e0851d in loop_iterate ../spa/plugins/support/loop.c:409
#9 0x7ffff709c21d in pw_main_loop_run ../src/pipewire/main-loop.c:148
#10 0x555555559722 in main ../src/daemon/pipewire.c:131
#11 0x7ffff62a528f (/usr/lib/libc.so.6+0x2928f)
#12 0x7ffff62a5349 in __libc_start_main (/usr/lib/libc.so.6+0x29349)
#13 0x5555555582a4 in _start (./src/daemon/pipewire+0x42a4)
0x61d000016728 is located 2216 bytes inside of 2264-byte region [0x61d000015e80,0x61d000016758)
freed by thread T0 here:
#0 0x7ffff798c672 in __interceptor_free /usr/src/debug/gcc/libsanitizer/asan/asan_malloc_linux.cpp:52
#1 0x7ffff70f9bc3 in pw_impl_node_destroy ../src/pipewire/impl-node.c:1880
#2 0x7ffff70d1d57 in global_destroy ../src/pipewire/impl-node.c:638
#3 0x7ffff7051a4f in pw_global_destroy ../src/pipewire/global.c:414
#4 0x7ffff6f82a68 in registry_destroy ../src/pipewire/impl-core.c:130
#5 0x7ffff3a5f349 in registry_demarshal_destroy ../src/modules/module-protocol-native/protocol-native.c:784
#6 0x7ffff3a2c9ed in process_messages ../src/modules/module-protocol-native.c:352
#7 0x7ffff3a2e2ea in connection_data ../src/modules/module-protocol-native.c:423
#8 0x7ffff3e09402 in source_io_func ../spa/plugins/support/loop.c:427
#9 0x7ffff3e0851d in loop_iterate ../spa/plugins/support/loop.c:409
#10 0x7ffff709c21d in pw_main_loop_run ../src/pipewire/main-loop.c:148
#11 0x555555559722 in main ../src/daemon/pipewire.c:131
#12 0x7ffff62a528f (/usr/lib/libc.so.6+0x2928f)
previously allocated by thread T0 here:
#0 0x7ffff798d411 in __interceptor_calloc /usr/src/debug/gcc/libsanitizer/asan/asan_malloc_linux.cpp:77
#1 0x7ffff70e5bb7 in pw_context_create_node ../src/pipewire/impl-node.c:1192
#2 0x7ffff28c748e in pw_spa_node_new ../src/modules/spa/spa-node.c:112
#3 0x7ffff28c9a9f in pw_spa_node_load ../src/modules/spa/spa-node.c:276
#4 0x7ffff28c1618 in create_object ../src/modules/spa/module-node-factory.c:134
#5 0x7ffff7106c4e in pw_impl_factory_create_object ../src/pipewire/impl-factory.c:273
#6 0x7ffff6f86dd7 in core_create_object ../src/pipewire/impl-core.c:349
#7 0x7ffff3a5cba9 in core_method_demarshal_create_object ../src/modules/module-protocol-native/protocol-native.c:680
#8 0x7ffff3a2c9ed in process_messages ../src/modules/module-protocol-native.c:352
#9 0x7ffff3a2e2ea in connection_data ../src/modules/module-protocol-native.c:423
#10 0x7ffff3e09402 in source_io_func ../spa/plugins/support/loop.c:427
#11 0x7ffff3e0851d in loop_iterate ../spa/plugins/support/loop.c:409
#12 0x7ffff709c21d in pw_main_loop_run ../src/pipewire/main-loop.c:148
#13 0x555555559722 in main ../src/daemon/pipewire.c:131
#14 0x7ffff62a528f (/usr/lib/libc.so.6+0x2928f)
SUMMARY: AddressSanitizer: heap-use-after-free ../spa/include/spa/utils/list.h:77 in spa_list_remove
Just like the real free() we should just ignore a NULL pointer, makes the
caller code easier for those instances where properties are optional.
Patch generated with concinelle with a few manual fixes.
Send create_object error messages to the new resource id so that
the client can better know what proxy is failing.
Use resource_remove when create_object fails because the core will
already send a remove_id on failure.
Try to send other errors to the proxy that made the request if
possible.
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.
The proxy API is the one that we would like to expose for applications
and the other API is used internally when implementing modules or
factories.
The current pw_core object is really a context for all objects so
name it that way. It also makes it possible to rename pw_core_proxy
to pw_proxy later.
Remove the parent_id from the global event. Remove the parent
and owner from the global object.
Use properties instead to mark parents and owners of objects.
Properties are easier to control for client exported objects and
usually a simple parent/child is not enough. For example, a client
exported node has the client as a parent but also the factory that
created the node.
Implement per channel volume on channelmix. Extend control on stream to
take an array of values when possible.
Remove name argument from pw_node_new and pw_device_new. We can pass
this as a property instead.
Improve properties on nodes to more closely match what pulseaudio does.
Don't let the monitor do too much with the udev properties but let the
session manager set the description and icon-names.
Remove some change_mask flags for things that don't change in
introspect. Use the flags to mark changes in -cli and -monitor.
Pass a factory_name in the object_info of monitor and device.
Restructure the factory name to mean something functionaly. With
the factory to library mapping this then means that the implementation
of certain factories can be configured in the config file.
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.
Make some more varargs error functions
Make pw_resource_error always just send the error to the resource id.
Make sure we send errors to the right destination.
Add proxy error event and emit it when the core finds an error for
the given proxy id.
The client error is supposed to be sent to all resources of a client
for the given global.
SPA_ID_* -> SPA_TYPE_*. We use 'type' for all registered types.
ID refers to either a registered type or an enum.
Improve introspection of object ids. Make 0 an invalid enum and
use it to look up the object id type.
Move some type-info files together.
Swap type and id of the object, we first specify the type and then
the id because the meaning of the id depends on the object type.
Do not use dynamic types anymore. The reason is that it's difficult:
- to maintain a shared type database over a network.
- the extra overhead when translating between processes and for
maintaining the translation tables.
- race conditions in translating in RT-threads, this is a problem
because we want to make event streams.
We now have simple enums with types and extension points for all
types. This is also nicer to use in general.
We don't need the mapper anymore or pass strings around as types.
There is a parallel type info system to get more info about ids and
enums and their hierarchy. It can also be used for debugging.
Add properties to global objects to make it easier to select what
nodes and objects to bind too. They can also be used to implement
permissions on the globals based on properties.
Add more error handling in _register.
Make more functions return a result code.
Make a separate pw_module_register, like all other objects.