screen-cast/src: Avoid undefined behavior with GSource

Follow the existing convention in Mutter and avoid downcasting
custom GSource structs.

This fixes the following warning:
    ../src/backends/meta-screen-cast-stream-src.c:1301:20: error: dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing]
     1301 |   g_clear_pointer ((GSource **) &priv->pipewire_source, g_source_destroy);
    /usr/include/glib-2.0/glib/glib-typeof.h:36:36: note: in definition of macro ‘glib_typeof’
       36 | #define glib_typeof(t) __typeof__ (t)
          |                                    ^
    ../src/backends/meta-screen-cast-stream-src.c:1301:3: note: in expansion of macro ‘g_clear_pointer’
     1301 |   g_clear_pointer ((GSource **) &priv->pipewire_source, g_source_destroy);
          |   ^~~~~~~~~~~~~~~

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2406>
This commit is contained in:
Dor Askayo 2022-05-07 23:48:22 +03:00 committed by Marge Bot
parent 0692ff5604
commit 61c9e344e4

View File

@ -78,7 +78,7 @@ static guint signals[N_SIGNALS];
typedef struct _MetaPipeWireSource typedef struct _MetaPipeWireSource
{ {
GSource base; GSource source;
MetaScreenCastStreamSrc *src; MetaScreenCastStreamSrc *src;
struct pw_loop *pipewire_loop; struct pw_loop *pipewire_loop;
@ -90,7 +90,7 @@ typedef struct _MetaScreenCastStreamSrcPrivate
struct pw_context *pipewire_context; struct pw_context *pipewire_context;
struct pw_core *pipewire_core; struct pw_core *pipewire_core;
MetaPipeWireSource *pipewire_source; GSource *pipewire_source;
struct spa_hook pipewire_core_listener; struct spa_hook pipewire_core_listener;
gboolean is_enabled; gboolean is_enabled;
@ -1145,7 +1145,7 @@ on_core_error (void *data,
} }
static gboolean static gboolean
pipewire_loop_source_prepare (GSource *base, pipewire_loop_source_prepare (GSource *source,
int *timeout) int *timeout)
{ {
*timeout = -1; *timeout = -1;
@ -1190,24 +1190,21 @@ static GSourceFuncs pipewire_source_funcs =
pipewire_loop_source_finalize pipewire_loop_source_finalize
}; };
static MetaPipeWireSource * static GSource *
create_pipewire_source (MetaScreenCastStreamSrc *src) create_pipewire_source (MetaScreenCastStreamSrc *src,
struct pw_loop *pipewire_loop)
{ {
GSource *source; GSource *source;
MetaPipeWireSource *pipewire_source; MetaPipeWireSource *pipewire_source;
source = g_source_new (&pipewire_source_funcs, sizeof (MetaPipeWireSource)); source = g_source_new (&pipewire_source_funcs, sizeof (MetaPipeWireSource));
g_source_set_name (source, "[mutter] PipeWire"); g_source_set_name (source, "[mutter] PipeWire");
pipewire_source = (MetaPipeWireSource *) source; pipewire_source = (MetaPipeWireSource *) source;
pipewire_source->src = src; pipewire_source->src = src;
pipewire_source->pipewire_loop = pw_loop_new (NULL); pipewire_source->pipewire_loop = pipewire_loop;
if (!pipewire_source->pipewire_loop)
{
g_source_unref ((GSource *) pipewire_source);
return NULL;
}
g_source_add_unix_fd (&pipewire_source->base, g_source_add_unix_fd (source,
pw_loop_get_fd (pipewire_source->pipewire_loop), pw_loop_get_fd (pipewire_source->pipewire_loop),
G_IO_IN | G_IO_ERR); G_IO_IN | G_IO_ERR);
@ -1215,7 +1212,7 @@ create_pipewire_source (MetaScreenCastStreamSrc *src)
g_source_attach (source, NULL); g_source_attach (source, NULL);
g_source_unref (source); g_source_unref (source);
return pipewire_source; return source;
} }
static const struct pw_core_events core_events = { static const struct pw_core_events core_events = {
@ -1231,8 +1228,17 @@ meta_screen_cast_stream_src_initable_init (GInitable *initable,
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (initable); MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (initable);
MetaScreenCastStreamSrcPrivate *priv = MetaScreenCastStreamSrcPrivate *priv =
meta_screen_cast_stream_src_get_instance_private (src); meta_screen_cast_stream_src_get_instance_private (src);
struct pw_loop *pipewire_loop;
priv->pipewire_source = create_pipewire_source (src); pipewire_loop = pw_loop_new (NULL);
if (!pipewire_loop)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Failed to create PipeWire loop");
return FALSE;
}
priv->pipewire_source = create_pipewire_source (src, pipewire_loop);
if (!priv->pipewire_source) if (!priv->pipewire_source)
{ {
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
@ -1240,7 +1246,7 @@ meta_screen_cast_stream_src_initable_init (GInitable *initable,
return FALSE; return FALSE;
} }
priv->pipewire_context = pw_context_new (priv->pipewire_source->pipewire_loop, priv->pipewire_context = pw_context_new (pipewire_loop,
NULL, 0); NULL, 0);
if (!priv->pipewire_context) if (!priv->pipewire_context)
{ {
@ -1298,7 +1304,7 @@ meta_screen_cast_stream_src_dispose (GObject *object)
g_clear_pointer (&priv->dmabuf_handles, g_hash_table_destroy); g_clear_pointer (&priv->dmabuf_handles, g_hash_table_destroy);
g_clear_pointer (&priv->pipewire_core, pw_core_disconnect); g_clear_pointer (&priv->pipewire_core, pw_core_disconnect);
g_clear_pointer (&priv->pipewire_context, pw_context_destroy); g_clear_pointer (&priv->pipewire_context, pw_context_destroy);
g_clear_pointer ((GSource **) &priv->pipewire_source, g_source_destroy); g_clear_pointer (&priv->pipewire_source, g_source_destroy);
G_OBJECT_CLASS (meta_screen_cast_stream_src_parent_class)->dispose (object); G_OBJECT_CLASS (meta_screen_cast_stream_src_parent_class)->dispose (object);
} }