Commit 00027222 authored by George Kiagiadakis's avatar George Kiagiadakis

simple-policy: compare client creation times so that the "last one wins"

When two clients have the same role, the current policy should
favor the newest client.
parent b05ae5f0
......@@ -27,7 +27,9 @@ struct _WpPipewireSimpleEndpoint
/* The global-id this endpoint refers to */
guint global_id;
/* properties */
gchar *role;
guint64 creation_time;
/* The task to signal the endpoint is initialized */
GTask *init_task;
......@@ -56,6 +58,7 @@ enum {
PROP_0,
PROP_GLOBAL_ID,
PROP_ROLE,
PROP_CREATION_TIME,
};
enum {
......@@ -359,6 +362,7 @@ static void
simple_endpoint_init (WpPipewireSimpleEndpoint * self)
{
self->init_abort = FALSE;
self->creation_time = (guint64) g_get_monotonic_time ();
}
static void
......@@ -416,6 +420,9 @@ simple_endpoint_get_property (GObject * object, guint property_id,
case PROP_ROLE:
g_value_set_string (value, self->role);
break;
case PROP_CREATION_TIME:
g_value_set_uint64 (value, self->creation_time);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
......@@ -541,6 +548,11 @@ simple_endpoint_class_init (WpPipewireSimpleEndpointClass * klass)
g_object_class_install_property (object_class, PROP_ROLE,
g_param_spec_string ("role", "role", "The role of the wrapped node", NULL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class, PROP_CREATION_TIME,
g_param_spec_uint64 ("creation-time", "creation-time",
"The time that this endpoint was created, in monotonic time",
0, G_MAXUINT64, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
}
void
......
......@@ -347,28 +347,44 @@ handle_client (WpPolicy *policy, WpEndpoint *ep)
}
static gint
compare_client_roles (gconstpointer a, gconstpointer b, gpointer user_data)
compare_client_priority (gconstpointer a, gconstpointer b, gpointer user_data)
{
GVariant *v = user_data;
WpEndpoint *ae = *(const gpointer *) a;
WpEndpoint *be = *(const gpointer *) b;
g_autofree gchar *a_role = NULL;
g_autofree gchar *b_role = NULL;
gint a_priority = 0, b_priority = 0;
gint ret = 0;
/* if no role priorities specified, everything is equal */
if (!v) return 0;
/* if no role priorities are specified, we treat all roles as equal */
if (v) {
g_autofree gchar *a_role = NULL;
g_autofree gchar *b_role = NULL;
gint a_priority = 0, b_priority = 0;
g_object_get (ae, "role", &a_role, NULL);
g_object_get (be, "role", &b_role, NULL);
g_object_get (ae, "role", &a_role, NULL);
g_object_get (be, "role", &b_role, NULL);
if (a_role)
g_variant_lookup (v, a_role, "i", &a_priority);
if (b_role)
g_variant_lookup (v, b_role, "i", &b_priority);
if (a_role)
g_variant_lookup (v, a_role, "i", &a_priority);
if (b_role)
g_variant_lookup (v, b_role, "i", &b_priority);
/* return b - a in order to sort descending */
return b_priority - a_priority;
/* return b - a in order to sort descending */
ret = b_priority - a_priority;
}
/* when role priority is equal, the newest client wins */
if (ret == 0) {
guint64 a_time = 0, b_time = 0;
g_object_get (ae, "creation-time", &a_time, NULL);
g_object_get (be, "creation-time", &b_time, NULL);
/* since a_time and b_time are expressed in system monotonic time,
* there is absolutely no chance that they will be equal */
ret = (b_time > a_time) ? 1 : -1;
}
return ret;
}
static gboolean
......@@ -393,7 +409,7 @@ simple_policy_rescan_in_idle (WpSimplePolicy *self)
endpoints = wp_endpoint_find (core, "Stream/Output/Audio");
if (endpoints && endpoints->len > 0) {
/* sort based on role priorities */
g_ptr_array_sort_with_data (endpoints, compare_client_roles,
g_ptr_array_sort_with_data (endpoints, compare_client_priority,
self->role_priorities);
/* link the highest priority client */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment