mirror of
https://gitlab.freedesktop.org/pipewire/wireplumber.git
synced 2026-05-05 05:28:01 +02:00
modules: handle error if the endpoint proxies could not be created
This commit is contained in:
parent
dbd763bc9c
commit
755f0bd862
5 changed files with 161 additions and 19 deletions
|
|
@ -31,6 +31,7 @@ struct _WpPipewireSimpleEndpoint
|
|||
|
||||
/* The task to signal the endpoint is initialized */
|
||||
GTask *init_task;
|
||||
gboolean init_abort;
|
||||
|
||||
/* The remote pipewire */
|
||||
WpRemotePipewire *remote_pipewire;
|
||||
|
|
@ -74,6 +75,37 @@ G_DEFINE_TYPE_WITH_CODE (WpPipewireSimpleEndpoint, simple_endpoint,
|
|||
G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE,
|
||||
wp_simple_endpoint_async_initable_init))
|
||||
|
||||
typedef GObject* (*WpObjectNewFinishFunc)(GObject *initable, GAsyncResult *res,
|
||||
GError **error);
|
||||
|
||||
static GObject *
|
||||
object_safe_new_finish(WpPipewireSimpleEndpoint * self, GObject *initable,
|
||||
GAsyncResult *res, WpObjectNewFinishFunc new_finish_func)
|
||||
{
|
||||
GObject *object = NULL;
|
||||
GError *error = NULL;
|
||||
|
||||
/* Return NULL if we are already aborting */
|
||||
if (self->init_abort)
|
||||
return NULL;
|
||||
|
||||
/* Get the object */
|
||||
object = G_OBJECT (new_finish_func (initable, res, &error));
|
||||
g_return_val_if_fail (object, NULL);
|
||||
|
||||
/* Check for error */
|
||||
if (error) {
|
||||
g_clear_object (&object);
|
||||
g_warning ("WpPipewireSimpleEndpoint:%p Aborting construction", self);
|
||||
self->init_abort = TRUE;
|
||||
g_task_return_error (self->init_task, error);
|
||||
g_clear_object (&self->init_task);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
static void
|
||||
node_proxy_param (void *object, int seq, uint32_t id,
|
||||
uint32_t index, uint32_t next, const struct spa_pod *param)
|
||||
|
|
@ -146,8 +178,10 @@ on_proxy_port_created(GObject *initable, GAsyncResult *res, gpointer data)
|
|||
WpProxyPort *proxy_port = NULL;
|
||||
|
||||
/* Get the proxy port */
|
||||
proxy_port = wp_proxy_port_new_finish(initable, res, NULL);
|
||||
g_return_if_fail (proxy_port);
|
||||
proxy_port = WP_PROXY_PORT (object_safe_new_finish (self, initable, res,
|
||||
(WpObjectNewFinishFunc)wp_proxy_port_new_finish));
|
||||
if (!proxy_port)
|
||||
return;
|
||||
|
||||
/* Add the proxy port to the array */
|
||||
g_return_if_fail (self->proxies_port);
|
||||
|
|
@ -168,6 +202,10 @@ on_port_added(WpRemotePipewire *rp, guint id, guint parent_id, gconstpointer p,
|
|||
WpPipewireSimpleEndpoint *self = d;
|
||||
struct pw_port_proxy *port_proxy = NULL;
|
||||
|
||||
/* Don't do anything if we are aborting */
|
||||
if (self->init_abort)
|
||||
return;
|
||||
|
||||
/* Only handle ports owned by this endpoint */
|
||||
if (parent_id != self->global_id)
|
||||
return;
|
||||
|
|
@ -222,8 +260,10 @@ on_proxy_node_created(GObject *initable, GAsyncResult *res, gpointer data)
|
|||
struct pw_node_proxy *node_proxy = NULL;
|
||||
|
||||
/* Get the proxy node */
|
||||
self->proxy_node = wp_proxy_node_new_finish(initable, res, NULL);
|
||||
g_return_if_fail (self->proxy_node);
|
||||
self->proxy_node = WP_PROXY_NODE (object_safe_new_finish (self, initable,
|
||||
res, (WpObjectNewFinishFunc)wp_proxy_node_new_finish));
|
||||
if (!self->proxy_node)
|
||||
return;
|
||||
|
||||
self->role = g_strdup (spa_dict_lookup (
|
||||
wp_proxy_node_get_info (self->proxy_node)->props, "media.role"));
|
||||
|
|
@ -319,6 +359,7 @@ wp_simple_endpoint_async_initable_init (gpointer iface, gpointer iface_data)
|
|||
static void
|
||||
simple_endpoint_init (WpPipewireSimpleEndpoint * self)
|
||||
{
|
||||
self->init_abort = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -29,11 +29,18 @@ on_endpoint_created(GObject *initable, GAsyncResult *res, gpointer d)
|
|||
struct impl *impl = d;
|
||||
WpEndpoint *endpoint = NULL;
|
||||
guint global_id = 0;
|
||||
GError *error = NULL;
|
||||
|
||||
/* Get the endpoint */
|
||||
endpoint = wp_endpoint_new_finish(initable, res, NULL);
|
||||
if (!endpoint)
|
||||
g_return_if_fail (endpoint);
|
||||
|
||||
/* Check for error */
|
||||
if (error) {
|
||||
g_clear_object (&endpoint);
|
||||
g_warning ("Failed to create alsa endpoint: %s", error->message);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get the endpoint global id */
|
||||
g_object_get (endpoint, "global-id", &global_id, NULL);
|
||||
|
|
|
|||
|
|
@ -27,11 +27,18 @@ on_endpoint_created(GObject *initable, GAsyncResult *res, gpointer d)
|
|||
struct module_data *data = d;
|
||||
WpEndpoint *endpoint = NULL;
|
||||
guint global_id = 0;
|
||||
GError *error = NULL;
|
||||
|
||||
/* Get the endpoint */
|
||||
endpoint = wp_endpoint_new_finish(initable, res, NULL);
|
||||
if (!endpoint)
|
||||
g_return_if_fail (endpoint);
|
||||
|
||||
/* Check for error */
|
||||
if (error) {
|
||||
g_clear_object (&endpoint);
|
||||
g_warning ("Failed to create client endpoint: %s", error->message);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get the endpoint global id */
|
||||
g_object_get (endpoint, "global-id", &global_id, NULL);
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ struct _WpPwAudioSoftdspEndpoint
|
|||
|
||||
/* The task to signal the endpoint is initialized */
|
||||
GTask *init_task;
|
||||
gboolean init_abort;
|
||||
|
||||
/* The remote pipewire */
|
||||
WpRemotePipewire *remote_pipewire;
|
||||
|
|
@ -71,6 +72,37 @@ G_DEFINE_TYPE_WITH_CODE (WpPwAudioSoftdspEndpoint, endpoint, WP_TYPE_ENDPOINT,
|
|||
G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE,
|
||||
wp_endpoint_async_initable_init))
|
||||
|
||||
typedef GObject* (*WpObjectNewFinishFunc)(GObject *initable, GAsyncResult *res,
|
||||
GError **error);
|
||||
|
||||
static GObject *
|
||||
object_safe_new_finish(WpPwAudioSoftdspEndpoint * self, GObject *initable,
|
||||
GAsyncResult *res, WpObjectNewFinishFunc new_finish_func)
|
||||
{
|
||||
GObject *object = NULL;
|
||||
GError *error = NULL;
|
||||
|
||||
/* Return NULL if we are already aborting */
|
||||
if (self->init_abort)
|
||||
return NULL;
|
||||
|
||||
/* Get the object */
|
||||
object = G_OBJECT (new_finish_func (initable, res, &error));
|
||||
g_return_val_if_fail (object, NULL);
|
||||
|
||||
/* Check for error */
|
||||
if (error) {
|
||||
g_clear_object (&object);
|
||||
g_warning ("WpPwAudioSoftdspEndpoint:%p Aborting construction", self);
|
||||
self->init_abort = TRUE;
|
||||
g_task_return_error (self->init_task, error);
|
||||
g_clear_object (&self->init_task);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
endpoint_prepare_link (WpEndpoint * ep, guint32 stream_id,
|
||||
WpEndpointLink * link, GVariant ** properties, GError ** error)
|
||||
|
|
@ -110,8 +142,10 @@ on_audio_dsp_stream_created(GObject *initable, GAsyncResult *res, gpointer data)
|
|||
g_autofree gchar *name = NULL;
|
||||
|
||||
/* Get the stream */
|
||||
dsp = wp_pw_audio_dsp_new_finish(initable, res, NULL);
|
||||
g_return_if_fail (dsp);
|
||||
dsp = WP_PW_AUDIO_DSP (object_safe_new_finish (self, initable, res,
|
||||
(WpObjectNewFinishFunc)wp_pw_audio_dsp_new_finish));
|
||||
if (!dsp)
|
||||
return;
|
||||
|
||||
/* Get the stream id */
|
||||
g_object_get (dsp, "id", &stream_id, "name", &name, NULL);
|
||||
|
|
@ -142,8 +176,10 @@ on_audio_dsp_converter_created(GObject *initable, GAsyncResult *res,
|
|||
int i;
|
||||
|
||||
/* Get the proxy dsp converter */
|
||||
self->converter = wp_pw_audio_dsp_new_finish(initable, res, NULL);
|
||||
g_return_if_fail (self->converter);
|
||||
self->converter = WP_PW_AUDIO_DSP (object_safe_new_finish (self, initable,
|
||||
res, (WpObjectNewFinishFunc)wp_pw_audio_dsp_new_finish));
|
||||
if (!self->converter)
|
||||
return;
|
||||
|
||||
/* Get the target and format */
|
||||
target = wp_pw_audio_dsp_get_info (self->converter);
|
||||
|
|
@ -177,8 +213,10 @@ on_proxy_node_created(GObject *initable, GAsyncResult *res, gpointer data)
|
|||
const struct spa_audio_info_raw *format = NULL;
|
||||
|
||||
/* Get the proxy node */
|
||||
self->proxy_node = wp_proxy_node_new_finish(initable, res, NULL);
|
||||
g_return_if_fail (self->proxy_node);
|
||||
self->proxy_node = WP_PROXY_NODE (object_safe_new_finish (self, initable,
|
||||
res, (WpObjectNewFinishFunc)wp_proxy_node_new_finish));
|
||||
if (!self->proxy_node)
|
||||
return;
|
||||
|
||||
/* Give a proper name to this endpoint based on ALSA properties */
|
||||
props = wp_proxy_node_get_info (self->proxy_node)->props;
|
||||
|
|
@ -208,8 +246,10 @@ on_proxy_port_created(GObject *initable, GAsyncResult *res, gpointer data)
|
|||
struct pw_node_proxy *node_proxy = NULL;
|
||||
|
||||
/* Get the proxy port */
|
||||
self->proxy_port = wp_proxy_port_new_finish(initable, res, NULL);
|
||||
g_return_if_fail (self->proxy_port);
|
||||
self->proxy_port = WP_PROXY_PORT (object_safe_new_finish (self, initable, res,
|
||||
(WpObjectNewFinishFunc)wp_proxy_port_new_finish));
|
||||
if (!self->proxy_port)
|
||||
return;
|
||||
|
||||
/* Create the proxy node async */
|
||||
node_proxy = wp_remote_pipewire_proxy_bind (self->remote_pipewire,
|
||||
|
|
@ -225,6 +265,10 @@ on_port_added(WpRemotePipewire *rp, guint id, guint parent_id, gconstpointer p,
|
|||
WpPwAudioSoftdspEndpoint *self = d;
|
||||
struct pw_port_proxy *port_proxy = NULL;
|
||||
|
||||
/* Don't do anything if we are aborting */
|
||||
if (self->init_abort)
|
||||
return;
|
||||
|
||||
/* Check if it is a node port and handle it */
|
||||
if (self->global_id != parent_id)
|
||||
return;
|
||||
|
|
@ -407,6 +451,7 @@ wp_endpoint_async_initable_init (gpointer iface, gpointer iface_data)
|
|||
static void
|
||||
endpoint_init (WpPwAudioSoftdspEndpoint * self)
|
||||
{
|
||||
self->init_abort = FALSE;
|
||||
self->dsps = g_ptr_array_new_with_free_func (g_object_unref);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ struct _WpPwAudioDsp
|
|||
|
||||
/* The task to signal the audio dsp is initialized */
|
||||
GTask *init_task;
|
||||
gboolean init_abort;
|
||||
|
||||
/* The remote pipewire */
|
||||
WpRemotePipewire *remote_pipewire;
|
||||
|
|
@ -75,6 +76,37 @@ G_DEFINE_TYPE_WITH_CODE (WpPwAudioDsp, wp_pw_audio_dsp, G_TYPE_OBJECT,
|
|||
G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE,
|
||||
wp_pw_audio_dsp_async_initable_init))
|
||||
|
||||
typedef GObject* (*WpObjectNewFinishFunc)(GObject *initable, GAsyncResult *res,
|
||||
GError **error);
|
||||
|
||||
static GObject *
|
||||
object_safe_new_finish(WpPwAudioDsp * self, GObject *initable,
|
||||
GAsyncResult *res, WpObjectNewFinishFunc new_finish_func)
|
||||
{
|
||||
GObject *object = NULL;
|
||||
GError *error = NULL;
|
||||
|
||||
/* Return NULL if we are already aborting */
|
||||
if (self->init_abort)
|
||||
return NULL;
|
||||
|
||||
/* Get the object */
|
||||
object = G_OBJECT (new_finish_func (initable, res, &error));
|
||||
g_return_val_if_fail (object, NULL);
|
||||
|
||||
/* Check for error */
|
||||
if (error) {
|
||||
g_clear_object (&object);
|
||||
g_warning ("WpPwAudioDsp:%p Aborting construction", self);
|
||||
self->init_abort = TRUE;
|
||||
g_task_return_error (self->init_task, error);
|
||||
g_clear_object (&self->init_task);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
guint
|
||||
wp_pw_audio_dsp_id_encode (guint stream_id, guint control_id)
|
||||
{
|
||||
|
|
@ -147,8 +179,10 @@ on_audio_dsp_port_created(GObject *initable, GAsyncResult *res,
|
|||
WpProxyPort *port_proxy = NULL;
|
||||
|
||||
/* Get the proxy port */
|
||||
port_proxy = wp_proxy_port_new_finish(initable, res, NULL);
|
||||
g_return_if_fail (port_proxy);
|
||||
port_proxy = WP_PROXY_PORT (object_safe_new_finish (self, initable, res,
|
||||
(WpObjectNewFinishFunc)wp_proxy_port_new_finish));
|
||||
if (!port_proxy)
|
||||
return;
|
||||
|
||||
/* Add the proxy port to the array */
|
||||
g_return_if_fail (self->port_proxies);
|
||||
|
|
@ -164,6 +198,10 @@ handled_ports_foreach_func (gpointer key, gpointer value, gpointer data)
|
|||
const guint id = GPOINTER_TO_INT (key);
|
||||
const guint parent_id = GPOINTER_TO_INT (value);
|
||||
|
||||
/* Don't do anything if we are aborting */
|
||||
if (self->init_abort)
|
||||
return;
|
||||
|
||||
/* Get the dsp info */
|
||||
g_return_if_fail (self->proxy);
|
||||
dsp_info = wp_proxy_node_get_info(self->proxy);
|
||||
|
|
@ -224,7 +262,8 @@ on_proxy_link_created(GObject *initable, GAsyncResult *res, gpointer data)
|
|||
WpPwAudioDsp *self = data;
|
||||
|
||||
/* Get the link */
|
||||
self->link_proxy = wp_proxy_link_new_finish(initable, res, NULL);
|
||||
self->link_proxy = WP_PROXY_LINK (object_safe_new_finish (self, initable,
|
||||
res, (WpObjectNewFinishFunc)wp_proxy_link_new_finish));
|
||||
g_return_if_fail (self->link_proxy);
|
||||
}
|
||||
|
||||
|
|
@ -366,8 +405,10 @@ on_audio_dsp_proxy_created(GObject *initable, GAsyncResult *res,
|
|||
struct spa_pod *param;
|
||||
|
||||
/* Get the audio dsp proxy */
|
||||
self->proxy = wp_proxy_node_new_finish(initable, res, NULL);
|
||||
g_return_if_fail (self->proxy);
|
||||
self->proxy = WP_PROXY_NODE (object_safe_new_finish (self, initable,
|
||||
res, (WpObjectNewFinishFunc)wp_proxy_node_new_finish));
|
||||
if (!self->proxy)
|
||||
return;
|
||||
|
||||
/* Add a custom dsp listener */
|
||||
pw_proxy = wp_proxy_get_pw_proxy(WP_PROXY(self->proxy));
|
||||
|
|
@ -575,6 +616,7 @@ wp_pw_audio_dsp_async_initable_init (gpointer iface, gpointer iface_data)
|
|||
static void
|
||||
wp_pw_audio_dsp_init (WpPwAudioDsp * self)
|
||||
{
|
||||
self->init_abort = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue