Unfortunately, libX11 has global error and I/O error handlers,
which make it inconvenient to use them from library code.
Since libX11 1.7.0, there is a per-display "exit_handler" which
is called from `_XIOError()`, however, the global I/O error
handler is still called before that, and that - by default -
calls `exit(1)` in `_XDefaultIOError()` after printing the error
to stderr.
To avoid exiting, custom handlers will be registered when
libpipewire-module-x11-bell.so is loaded given that at
that moment the default handlers are installed.
When the shared object is unloaded, the handlers will
be reset to the default ones given that the currently
registered handlers are the ones that were registered
when the module was loaded.
The logic only works correctly if there are no concurrent
calls to `XSet{IO}ErrorHandler()` while `{set,restore}_x11_handlers()`
is running. Since module-x11-bell is probably mostly going to
be loaded in `pipewire-pulse`, this seems like a reasonable
assumption to make.
Add `pw_impl_module_schedule_destroy()` which will
schedule a call to `pw_impl_module_destroy()` on
the module's context's work queue.
For now, do not add it to the public impl-module.h header,
only private.h.
Many modules cannot load without a work queue,
neither links nor nodes can be created without it.
It's probably better to try to create it immediately
when the context is created. This elliminates the
need for checking whether `pw_context_get_work_queue`
succeeded or not.
`x11_close()` is no longer needed since X11 errors
are now considered fatal, so `module_destroy()` will
be called if `x11_connect()` fails, which means that
the code from `x11_close()` can be moved there.
Older gcc versions seem to require the members to appear in the
designated initializer in the order they are in the definition of
the struct when compiling C++.
otherwise compilation fails with:
../spa/plugins/aec/aec-webrtc.cpp:167:1: sorry, unimplemented:
non-trivial designated initializers not supported
};
^
Place the methods on the interface so that we can call them.
Rename create to init because that is what it does.
Add support for listener and events so that we can signal property
changes later.
Move all backends to dynamic libaries loaded with spa_plugin_loader so
new backends not needs changes in pipewire or pipewire dependency to
external code
Change-Id: I702ce047598d0c318d6dc6ac8248062a5c12f643
Use the max error to do a resync. Don't reset the dll, there is no
reason for that.
Don't use _rewind, but instead limit the amount of samples we read and
write
Should keep more stable sync in most cases.
In some cases it is possible for `pw_context_conf_section_for_each()`
to not set `res` at all, which leads to an indeterminate value being returned.
Fix that by setting `res` to 0 initially.
module-combine-sink should become loaded only after its input stream,
and all explicitly specified output sink stream nodes appear. Since
output sinks may appear on the manager after a delay, wait for them only
up to a timeout, and fail load after that.
Fail load if there are errors in input stream, or in an explicitly
specified output.
This is needed for Zoom sound sharing to work. Pulseaudio additionally
fails the module load if streams fail to connect, but we do not do that
here at the moment.
Operations sync manager, so use that.
On Pulseaudio, module unload is async procedure. However, this race
condition may be hard to hit in practice, whereas on pipewire-pulse it's
not hard. E.g. Zoom appears to assume that modules are unloaded
synchronously.
Sync client's manager, before returning from module load, also for async
module loads. This is because the module load may have its own core, so
even though it has made changes on server, the client manager might not
see them yet.
Fix this by syncing client->manager before operation return.
If card busy check fails due to error, just log info message and
consider the card not busy.
For kernels with CONFIG_SND_PROCFS=n, /proc/asound is not present, and
we have to handle that. It's also better to fail open here, rather than
end up with missing devices.
In context.exec after forking, if execvp returns we have to exit since
we're in the child process.
To avoid zombies, either SIGCHLD need to be handled/ignored, or
double-fork to create orphan processes. This is in library code, so it
seems best to just double-fork.
Add a module for a fallback dummy sink, which appears dynamically when
no other sinks are present.
Enable it for pipewire-pulse, because Pulseaudio will also show
dynamically a dummy sink.