core: fix WpLoopSource lifecycle
Currently nothing removes the WpLoopSource from the main context, and we moreover are creating and attaching unused WpLoopSources when sharing same pw_context between multiple WpCore. Fix this by keeping track of the WpLoopSource in the pw_context user data, only creating them when needed, and finalizing it after the context is destroyed.
This commit is contained in:

committed by
George Kiagiadakis

parent
7997fd490b
commit
7f30adeb42
@@ -200,6 +200,11 @@ struct _WpCore
|
|||||||
GHashTable *async_tasks; // <int seq, GTask*>
|
GHashTable *async_tasks; // <int seq, GTask*>
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct context_data {
|
||||||
|
grefcount rc;
|
||||||
|
GSource *loop_source;
|
||||||
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_G_MAIN_CONTEXT,
|
PROP_G_MAIN_CONTEXT,
|
||||||
@@ -322,16 +327,12 @@ static void
|
|||||||
wp_core_constructed (GObject *object)
|
wp_core_constructed (GObject *object)
|
||||||
{
|
{
|
||||||
WpCore *self = WP_CORE (object);
|
WpCore *self = WP_CORE (object);
|
||||||
g_autoptr (GSource) source = NULL;
|
|
||||||
|
|
||||||
/* loop */
|
|
||||||
source = wp_loop_source_new ();
|
|
||||||
g_source_attach (source, self->g_main_context);
|
|
||||||
|
|
||||||
/* context */
|
/* context */
|
||||||
if (!self->pw_context) {
|
if (!self->pw_context) {
|
||||||
struct pw_properties *p = NULL;
|
struct pw_properties *p = NULL;
|
||||||
const gchar *str = NULL;
|
const gchar *str = NULL;
|
||||||
|
g_autoptr (GSource) source = wp_loop_source_new ();
|
||||||
|
|
||||||
/* use our own configuration file, if specified */
|
/* use our own configuration file, if specified */
|
||||||
if (self->conf) {
|
if (self->conf) {
|
||||||
@@ -359,7 +360,7 @@ wp_core_constructed (GObject *object)
|
|||||||
self->properties = NULL;
|
self->properties = NULL;
|
||||||
|
|
||||||
self->pw_context = pw_context_new (WP_LOOP_SOURCE(source)->loop, p,
|
self->pw_context = pw_context_new (WP_LOOP_SOURCE(source)->loop, p,
|
||||||
sizeof (grefcount));
|
sizeof (struct context_data));
|
||||||
g_return_if_fail (self->pw_context);
|
g_return_if_fail (self->pw_context);
|
||||||
|
|
||||||
/* use the same config option as pipewire to set the log level */
|
/* use the same config option as pipewire to set the log level */
|
||||||
@@ -375,14 +376,18 @@ wp_core_constructed (GObject *object)
|
|||||||
wp_conf_parse_pw_context_sections (self->conf, self->pw_context);
|
wp_conf_parse_pw_context_sections (self->conf, self->pw_context);
|
||||||
|
|
||||||
/* Init refcount */
|
/* Init refcount */
|
||||||
grefcount *rc = pw_context_get_user_data (self->pw_context);
|
struct context_data *cd = pw_context_get_user_data (self->pw_context);
|
||||||
g_return_if_fail (rc);
|
g_return_if_fail (cd);
|
||||||
g_ref_count_init (rc);
|
g_ref_count_init (&cd->rc);
|
||||||
|
cd->loop_source = g_source_ref (source);
|
||||||
|
|
||||||
|
/* Start source */
|
||||||
|
g_source_attach (source, self->g_main_context);
|
||||||
} else {
|
} else {
|
||||||
/* Increase refcount */
|
/* Increase refcount */
|
||||||
grefcount *rc = pw_context_get_user_data (self->pw_context);
|
struct context_data *cd = pw_context_get_user_data (self->pw_context);
|
||||||
g_return_if_fail (rc);
|
g_return_if_fail (cd);
|
||||||
g_ref_count_inc (rc);
|
g_ref_count_inc (&cd->rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
G_OBJECT_CLASS (wp_core_parent_class)->constructed (object);
|
G_OBJECT_CLASS (wp_core_parent_class)->constructed (object);
|
||||||
@@ -403,14 +408,19 @@ static void
|
|||||||
wp_core_finalize (GObject * obj)
|
wp_core_finalize (GObject * obj)
|
||||||
{
|
{
|
||||||
WpCore *self = WP_CORE (obj);
|
WpCore *self = WP_CORE (obj);
|
||||||
grefcount *rc = pw_context_get_user_data (self->pw_context);
|
struct context_data *cd = pw_context_get_user_data (self->pw_context);
|
||||||
g_return_if_fail (rc);
|
g_return_if_fail (cd);
|
||||||
|
|
||||||
wp_core_disconnect (self);
|
wp_core_disconnect (self);
|
||||||
|
|
||||||
/* Clear pw-context if refcount reaches 0 */
|
/* Clear pw-context if refcount reaches 0 */
|
||||||
if (g_ref_count_dec (rc))
|
if (g_ref_count_dec (&cd->rc)) {
|
||||||
|
GSource *source = cd->loop_source;
|
||||||
|
|
||||||
g_clear_pointer (&self->pw_context, pw_context_destroy);
|
g_clear_pointer (&self->pw_context, pw_context_destroy);
|
||||||
|
g_source_destroy (source);
|
||||||
|
g_source_unref (source);
|
||||||
|
}
|
||||||
|
|
||||||
g_clear_pointer (&self->properties, wp_properties_unref);
|
g_clear_pointer (&self->properties, wp_properties_unref);
|
||||||
g_clear_pointer (&self->g_main_context, g_main_context_unref);
|
g_clear_pointer (&self->g_main_context, g_main_context_unref);
|
||||||
|
Reference in New Issue
Block a user