From 374511c52cb19bd8eb187c2f2aba2c86f396cb95 Mon Sep 17 00:00:00 2001 From: Martin Willi Date: Thu, 1 May 2014 10:57:38 +0200 Subject: [PATCH] vici: Ensure we have no active users before mangling event client registrations --- src/libcharon/plugins/vici/vici_dispatcher.c | 48 ++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/src/libcharon/plugins/vici/vici_dispatcher.c b/src/libcharon/plugins/vici/vici_dispatcher.c index 0df867a..6db36fb 100644 --- a/src/libcharon/plugins/vici/vici_dispatcher.c +++ b/src/libcharon/plugins/vici/vici_dispatcher.c @@ -129,10 +129,19 @@ static void register_event(private_vici_dispatcher_t *this, char *name, event_t *event; this->mutex->lock(this->mutex); - event = this->events->get(this->events, name); - if (event) + while (TRUE) { - array_insert(event->clients, ARRAY_TAIL, &id); + event = this->events->get(this->events, name); + if (!event) + { + break; + } + if (!event->uses) + { + array_insert(event->clients, ARRAY_TAIL, &id); + break; + } + this->cond->wait(this->cond, this->mutex); } this->mutex->unlock(this->mutex); @@ -160,20 +169,29 @@ static void unregister_event(private_vici_dispatcher_t *this, char *name, bool found = FALSE; this->mutex->lock(this->mutex); - event = this->events->get(this->events, name); - if (event) + while (TRUE) { - enumerator = array_create_enumerator(event->clients); - while (enumerator->enumerate(enumerator, ¤t)) + event = this->events->get(this->events, name); + if (!event) { - if (*current == id) + break; + } + if (!event->uses) + { + enumerator = array_create_enumerator(event->clients); + while (enumerator->enumerate(enumerator, ¤t)) { - array_remove_at(event->clients, enumerator); - found = TRUE; - break; + if (*current == id) + { + array_remove_at(event->clients, enumerator); + found = TRUE; + break; + } } + enumerator->destroy(enumerator); + break; } - enumerator->destroy(enumerator); + this->cond->wait(this->cond, this->mutex); } this->mutex->unlock(this->mutex); @@ -340,11 +358,15 @@ CALLBACK(disconnect, void, event_t *event; u_int *current; - /* deregister all clients */ + /* deregister client from all events */ this->mutex->lock(this->mutex); events = this->events->create_enumerator(this->events); while (events->enumerate(events, NULL, &event)) { + while (event->uses) + { + this->cond->wait(this->cond, this->mutex); + } ids = array_create_enumerator(event->clients); while (ids->enumerate(ids, ¤t)) { -- 2.7.4