peer-cfg: Replace equal child configs with newly added ones

Otherwise, renamed child configs would still be known to the daemon
under their old name.

Fixes #2746.
This commit is contained in:
Tobias Brunner
2018-09-10 17:45:07 +02:00
parent 375dfb9076
commit 40ed812442
2 changed files with 15 additions and 21 deletions
+14 -18
View File
@@ -258,48 +258,44 @@ METHOD(peer_cfg_t, replace_child_cfgs, enumerator_t*,
private_peer_cfg_t *this, peer_cfg_t *other_pub) private_peer_cfg_t *this, peer_cfg_t *other_pub)
{ {
private_peer_cfg_t *other = (private_peer_cfg_t*)other_pub; private_peer_cfg_t *other = (private_peer_cfg_t*)other_pub;
linked_list_t *removed, *added; linked_list_t *new_cfgs, *removed, *added;
enumerator_t *mine, *others; enumerator_t *mine, *others;
child_cfg_t *my_cfg, *other_cfg; child_cfg_t *my_cfg, *other_cfg;
child_cfgs_replace_enumerator_t *enumerator; child_cfgs_replace_enumerator_t *enumerator;
bool found; bool found;
removed = linked_list_create(); added = linked_list_create();
other->lock->read_lock(other->lock); other->lock->read_lock(other->lock);
added = linked_list_create_from_enumerator( new_cfgs = linked_list_create_from_enumerator(
other->child_cfgs->create_enumerator(other->child_cfgs)); other->child_cfgs->create_enumerator(other->child_cfgs));
added->invoke_offset(added, offsetof(child_cfg_t, get_ref)); new_cfgs->invoke_offset(new_cfgs, offsetof(child_cfg_t, get_ref));
other->lock->unlock(other->lock); other->lock->unlock(other->lock);
this->lock->write_lock(this->lock); this->lock->write_lock(this->lock);
others = added->create_enumerator(added); removed = this->child_cfgs;
mine = this->child_cfgs->create_enumerator(this->child_cfgs); this->child_cfgs = new_cfgs;
while (mine->enumerate(mine, &my_cfg)) others = new_cfgs->create_enumerator(new_cfgs);
mine = removed->create_enumerator(removed);
while (others->enumerate(others, &other_cfg))
{ {
found = FALSE; found = FALSE;
while (others->enumerate(others, &other_cfg)) while (mine->enumerate(mine, &my_cfg))
{ {
if (my_cfg->equals(my_cfg, other_cfg)) if (my_cfg->equals(my_cfg, other_cfg))
{ {
added->remove_at(added, others); removed->remove_at(removed, mine);
other_cfg->destroy(other_cfg); my_cfg->destroy(my_cfg);
found = TRUE; found = TRUE;
break; break;
} }
} }
added->reset_enumerator(added, others); removed->reset_enumerator(removed, mine);
if (!found) if (!found)
{ {
this->child_cfgs->remove_at(this->child_cfgs, mine); added->insert_last(added, other_cfg->get_ref(other_cfg));
removed->insert_last(removed, my_cfg);
} }
} }
while (others->enumerate(others, &other_cfg))
{
this->child_cfgs->insert_last(this->child_cfgs,
other_cfg->get_ref(other_cfg));
}
others->destroy(others); others->destroy(others);
mine->destroy(mine); mine->destroy(mine);
this->lock->unlock(this->lock); this->lock->unlock(this->lock);
+1 -3
View File
@@ -157,11 +157,9 @@ struct peer_cfg_t {
/** /**
* Replace the CHILD configs with those in the given PEER config. * Replace the CHILD configs with those in the given PEER config.
* *
* Configs that are equal are not replaced.
*
* The enumerator enumerates the removed and added CHILD configs * The enumerator enumerates the removed and added CHILD configs
* (child_cfg_t*, bool), where the flag is FALSE for removed configs and * (child_cfg_t*, bool), where the flag is FALSE for removed configs and
* TRUE for added configs. * TRUE for added configs. Configs that are equal are not enumerated.
* *
* @param other other config to get CHILD configs from * @param other other config to get CHILD configs from
* @return an enumerator over removed/added CHILD configs * @return an enumerator over removed/added CHILD configs