modules: handle error if the endpoint proxies could not be created

This commit is contained in:
Julian Bouzas 2019-07-11 13:50:37 -04:00 committed by George Kiagiadakis
parent dbd763bc9c
commit 755f0bd862
5 changed files with 161 additions and 19 deletions

View file

@ -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

View file

@ -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);

View file

@ -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);

View file

@ -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);
}

View file

@ -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