properties: return if property changed

make property_set functions return 1 if there was a change.
Only emit property change notifications when something actually
changed.
Try to only copy property value when needed.
This commit is contained in:
Wim Taymans 2018-10-04 15:18:31 +02:00
parent 0e2885b599
commit 31f4ceb137
8 changed files with 65 additions and 40 deletions

View file

@ -195,7 +195,7 @@ struct pw_client *pw_client_new(struct pw_core *core,
pw_core_add_listener(core, &impl->core_listener, &core_events, impl);
this->info.props = this->properties ? &this->properties->dict : NULL;
this->info.props = &this->properties->dict;
return this;
}
@ -321,8 +321,7 @@ void pw_client_destroy(struct pw_client *client)
pw_map_clear(&client->objects);
pw_array_clear(&impl->permissions);
if (client->properties)
pw_properties_free(client->properties);
pw_properties_free(client->properties);
free(impl);
}
@ -354,20 +353,17 @@ const struct pw_client_info *pw_client_get_info(struct pw_client *client)
int pw_client_update_properties(struct pw_client *client, const struct spa_dict *dict)
{
struct pw_resource *resource;
uint32_t i, changed = 0;
if (client->properties == NULL) {
if (dict)
client->properties = pw_properties_new_dict(dict);
} else {
uint32_t i;
for (i = 0; i < dict->n_items; i++)
changed += pw_properties_set(client->properties,
dict->items[i].key, dict->items[i].value);
for (i = 0; i < dict->n_items; i++)
pw_properties_set(client->properties,
dict->items[i].key, dict->items[i].value);
}
if (!changed)
return 0;
client->info.change_mask |= PW_CLIENT_CHANGE_MASK_PROPS;
client->info.props = client->properties ? &client->properties->dict : NULL;
client->info.props = &client->properties->dict;
pw_client_events_info_changed(client, &client->info);
@ -376,7 +372,7 @@ int pw_client_update_properties(struct pw_client *client, const struct spa_dict
client->info.change_mask = 0;
return 0;
return changed;
}
struct permissions_update {

View file

@ -573,10 +573,13 @@ const struct pw_properties *pw_core_get_properties(struct pw_core *core)
int pw_core_update_properties(struct pw_core *core, const struct spa_dict *dict)
{
struct pw_resource *resource;
uint32_t i;
uint32_t i, changed = 0;
for (i = 0; i < dict->n_items; i++)
pw_properties_set(core->properties, dict->items[i].key, dict->items[i].value);
changed += pw_properties_set(core->properties, dict->items[i].key, dict->items[i].value);
if (!changed)
return 0;
core->info.change_mask = PW_CORE_CHANGE_MASK_PROPS;
core->info.props = &core->properties->dict;
@ -588,7 +591,7 @@ int pw_core_update_properties(struct pw_core *core, const struct spa_dict *dict)
core->info.change_mask = 0;
return 0;
return changed;
}
int pw_core_for_each_global(struct pw_core *core,

View file

@ -334,10 +334,13 @@ const struct pw_properties *pw_module_get_properties(struct pw_module *module)
int pw_module_update_properties(struct pw_module *module, const struct spa_dict *dict)
{
struct pw_resource *resource;
uint32_t i;
uint32_t i, changed = 0;
for (i = 0; i < dict->n_items; i++)
pw_properties_set(module->properties, dict->items[i].key, dict->items[i].value);
changed += pw_properties_set(module->properties, dict->items[i].key, dict->items[i].value);
if (!changed)
return 0;
module->info.props = &module->properties->dict;
@ -346,7 +349,7 @@ int pw_module_update_properties(struct pw_module *module, const struct spa_dict
pw_module_resource_info(resource, &module->info);
module->info.change_mask = 0;
return 0;
return changed;
}
const struct pw_module_info *

View file

@ -721,15 +721,19 @@ const struct pw_properties *pw_node_get_properties(struct pw_node *node)
int pw_node_update_properties(struct pw_node *node, const struct spa_dict *dict)
{
struct pw_resource *resource;
uint32_t i;
uint32_t i, changed = 0;
for (i = 0; i < dict->n_items; i++)
pw_properties_set(node->properties, dict->items[i].key, dict->items[i].value);
changed += pw_properties_set(node->properties, dict->items[i].key, dict->items[i].value);
pw_log_debug("node %p: updated %d properties", node, changed);
if (!changed)
return 0;
check_properties(node);
node->info.props = &node->properties->dict;
node->info.change_mask |= PW_NODE_CHANGE_MASK_PROPS;
pw_node_events_info_changed(node, &node->info);
@ -738,7 +742,7 @@ int pw_node_update_properties(struct pw_node *node, const struct spa_dict *dict)
node->info.change_mask = 0;
return 0;
return changed;
}
static void node_done(void *data, int seq, int res)

View file

@ -283,13 +283,17 @@ const struct pw_properties *pw_port_get_properties(struct pw_port *port)
int pw_port_update_properties(struct pw_port *port, const struct spa_dict *dict)
{
struct pw_resource *resource;
uint32_t i;
uint32_t i, changed = 0;
for (i = 0; i < dict->n_items; i++)
pw_properties_set(port->properties, dict->items[i].key, dict->items[i].value);
changed += pw_properties_set(port->properties, dict->items[i].key, dict->items[i].value);
pw_log_debug("port %p: updated %d properties", port, changed);
if (!changed)
return 0;
port->info.props = &port->properties->dict;
port->info.change_mask |= PW_PORT_CHANGE_MASK_PROPS;
pw_port_events_info_changed(port, &port->info);
@ -298,7 +302,7 @@ int pw_port_update_properties(struct pw_port *port, const struct spa_dict *dict)
port->info.change_mask = 0;
return 0;
return changed;
}
struct pw_node *pw_port_get_node(struct pw_port *port)

View file

@ -247,31 +247,39 @@ void pw_properties_free(struct pw_properties *properties)
free(impl);
}
static int do_replace(struct pw_properties *properties, const char *key, char *value)
static int do_replace(struct pw_properties *properties, const char *key, char *value, bool copy)
{
struct properties *impl = SPA_CONTAINER_OF(properties, struct properties, this);
int index = find_index(properties, key);
if (index == -1) {
add_func(properties, strdup(key), value);
if (value == NULL)
return 0;
add_func(properties, strdup(key), copy ? strdup(value) : value);
} else {
struct spa_dict_item *item =
pw_array_get_unchecked(&impl->items, index, struct spa_dict_item);
clear_item(item);
if (value && strcmp(item->value, value) == 0) {
if (!copy)
free(value);
return 0;
}
if (value == NULL) {
struct spa_dict_item *other = pw_array_get_unchecked(&impl->items,
pw_array_get_len(&impl->items, struct spa_dict_item) - 1,
struct spa_dict_item);
clear_item(item);
item->key = other->key;
item->value = other->value;
impl->items.size -= sizeof(struct spa_dict_item);
} else {
item->key = strdup(key);
item->value = value;
free((char *) item->value);
item->value = copy ? strdup(value) : value;
}
}
return 0;
return 1;
}
/** Set a property value
@ -279,6 +287,9 @@ static int do_replace(struct pw_properties *properties, const char *key, char *v
* \param properties the properties to change
* \param key a key
* \param value a value or NULL to remove the key
* \return 1 if the properties were changed. 0 if nothing was changed because
* the property already existed with the same value or because the key to remove
* did not exist.
*
* Set the property in \a properties with \a key to \a value. Any previous value
* of \a key will be overwritten. When \a value is NULL, the key will be
@ -288,7 +299,7 @@ static int do_replace(struct pw_properties *properties, const char *key, char *v
*/
int pw_properties_set(struct pw_properties *properties, const char *key, const char *value)
{
return do_replace(properties, key, value ? strdup(value) : NULL);
return do_replace(properties, key, (char*)value, true);
}
int
@ -297,7 +308,7 @@ pw_properties_setva(struct pw_properties *properties,
{
char *value;
vasprintf(&value, format, args);
return do_replace(properties, key, value);
return do_replace(properties, key, value, false);
}
/** Set a property value by format

View file

@ -330,16 +330,20 @@ const struct pw_properties *pw_remote_get_properties(struct pw_remote *remote)
int pw_remote_update_properties(struct pw_remote *remote, const struct spa_dict *dict)
{
uint32_t i;
uint32_t i, changed = 0;
for (i = 0; i < dict->n_items; i++)
pw_properties_set(remote->properties, dict->items[i].key, dict->items[i].value);
changed += pw_properties_set(remote->properties, dict->items[i].key, dict->items[i].value);
if (!changed)
return 0;
if (remote->core_proxy)
pw_core_proxy_client_update(remote->core_proxy, &remote->properties->dict);
return 0;
return changed;
}
void *pw_remote_get_user_data(struct pw_remote *remote)
{
return remote->user_data;

View file

@ -290,7 +290,7 @@ static void print_port(struct proxy_data *data)
if (print_all) {
int i;
printf(" \tdirection: \"%s\"\n", pw_direction_as_string(info->direction));
printf("%c\tparams:\n", MARK_CHANGE(1));
printf("%c\tparams:\n", MARK_CHANGE(2));
for (i = 0; i < data->n_params; i++) {
if (spa_pod_is_object_type(data->params[i], SPA_TYPE_OBJECT_Format))
spa_debug_format(12, NULL, data->params[i]);