diff options
author | Martin Willi <martin@strongswan.org> | 2008-10-16 11:32:43 +0000 |
---|---|---|
committer | Martin Willi <martin@strongswan.org> | 2008-10-16 11:32:43 +0000 |
commit | e17353fc31fb83852b196edfb52f4e091acbc0e3 (patch) | |
tree | ca17a0582a63d6882ae1e6559034299da10226a4 /src | |
parent | f868dc0ca27ee683b15e9591bc2aec1b405a258c (diff) | |
download | strongswan-e17353fc31fb83852b196edfb52f4e091acbc0e3.tar.bz2 strongswan-e17353fc31fb83852b196edfb52f4e091acbc0e3.tar.xz |
bus uses finally recusive locking
other small fixes
Diffstat (limited to 'src')
-rw-r--r-- | src/charon/bus/bus.c | 105 |
1 files changed, 58 insertions, 47 deletions
diff --git a/src/charon/bus/bus.c b/src/charon/bus/bus.c index 763ea0b38..eb8390856 100644 --- a/src/charon/bus/bus.c +++ b/src/charon/bus/bus.c @@ -18,6 +18,7 @@ #include "bus.h" #include <pthread.h> +#include <stdint.h> #include <daemon.h> #include <utils/mutex.h> @@ -87,7 +88,7 @@ struct entry_t { /** * are we currently calling this listener */ - bool calling; + int calling; /** * condvar where active listeners wait @@ -104,7 +105,7 @@ static entry_t *entry_create(listener_t *listener, bool blocker) this->listener = listener; this->blocker = blocker; - this->calling = FALSE; + this->calling = 0; this->condvar = condvar_create(CONDVAR_DEFAULT); return this; @@ -124,12 +125,12 @@ static void entry_destroy(entry_t *entry) * pthread_self returns large and ugly numbers, use this function * for logging; these numbers are incremental starting at 1 */ -static int get_thread_number(private_bus_t *this) +static u_int get_thread_number(private_bus_t *this) { - static long current_num = 0; - long stored_num; + static uintptr_t current_num = 0; + uintptr_t stored_num; - stored_num = (long)pthread_getspecific(this->thread_id); + stored_num = (uintptr_t)pthread_getspecific(this->thread_id); if (stored_num == 0) { /* first call of current thread */ pthread_setspecific(this->thread_id, (void*)++current_num); @@ -260,7 +261,7 @@ static bool log_cb(entry_t *entry, log_data_t *data) { /* avoid recursive calls */ return FALSE; } - entry->calling = TRUE; + entry->calling++; va_copy(args, data->args); if (!entry->listener->log(entry->listener, data->group, data->level, data->thread, data->ike_sa, data->format, args)) @@ -275,11 +276,11 @@ static bool log_cb(entry_t *entry, log_data_t *data) entry_destroy(entry); } va_end(args); - entry->calling = FALSE; + entry->calling--; return TRUE; } va_end(args); - entry->calling = FALSE; + entry->calling--; return FALSE; } @@ -320,6 +321,21 @@ static void log_(private_bus_t *this, debug_t group, level_t level, va_end(args); } +static void unregister_listener(private_bus_t *this, entry_t *entry, + enumerator_t *enumerator) +{ + if (entry->blocker) + { + entry->blocker = FALSE; + entry->condvar->signal(entry->condvar); + } + else + { + entry_destroy(entry); + } + this->listeners->remove_at(this->listeners, enumerator); +} + /** * Implementation of bus_t.ike_state_change */ @@ -328,24 +344,22 @@ static void ike_state_change(private_bus_t *this, ike_sa_t *ike_sa, { enumerator_t *enumerator; entry_t *entry; + bool keep; this->mutex->lock(this->mutex); enumerator = this->listeners->create_enumerator(this->listeners); while (enumerator->enumerate(enumerator, &entry)) { - if (entry->listener->ike_state_change && - !entry->listener->ike_state_change(entry->listener, ike_sa, state)) + if (entry->calling || !entry->listener->ike_state_change) { - if (entry->blocker) - { - entry->blocker = FALSE; - entry->condvar->signal(entry->condvar); - } - else - { - entry_destroy(entry); - } - this->listeners->remove_at(this->listeners, enumerator); + continue; + } + entry->calling++; + keep = entry->listener->ike_state_change(entry->listener, ike_sa, state); + entry->calling--; + if (!keep) + { + unregister_listener(this, entry, enumerator); break; } } @@ -362,6 +376,7 @@ static void child_state_change(private_bus_t *this, child_sa_t *child_sa, enumerator_t *enumerator; ike_sa_t *ike_sa; entry_t *entry; + bool keep; ike_sa = pthread_getspecific(this->thread_sa); @@ -369,20 +384,17 @@ static void child_state_change(private_bus_t *this, child_sa_t *child_sa, enumerator = this->listeners->create_enumerator(this->listeners); while (enumerator->enumerate(enumerator, &entry)) { - if (entry->listener->child_state_change && - !entry->listener->child_state_change(entry->listener, ike_sa, - child_sa, state)) + if (entry->calling || !entry->listener->child_state_change) { - if (entry->blocker) - { - entry->blocker = FALSE; - entry->condvar->signal(entry->condvar); - } - else - { - entry_destroy(entry); - } - this->listeners->remove_at(this->listeners, enumerator); + continue; + } + entry->calling++; + keep = entry->listener->child_state_change(entry->listener, ike_sa, + child_sa, state); + entry->calling--; + if (!keep) + { + unregister_listener(this, entry, enumerator); break; } } @@ -398,6 +410,7 @@ static void message(private_bus_t *this, message_t *message, bool incoming) enumerator_t *enumerator; ike_sa_t *ike_sa; entry_t *entry; + bool keep; ike_sa = pthread_getspecific(this->thread_sa); @@ -405,19 +418,17 @@ static void message(private_bus_t *this, message_t *message, bool incoming) enumerator = this->listeners->create_enumerator(this->listeners); while (enumerator->enumerate(enumerator, &entry)) { - if (entry->listener->message && - !entry->listener->message(entry->listener, ike_sa, message, incoming)) + if (entry->calling || !entry->listener->message) { - if (entry->blocker) - { - entry->blocker = FALSE; - entry->condvar->signal(entry->condvar); - } - else - { - entry_destroy(entry); - } - this->listeners->remove_at(this->listeners, enumerator); + continue; + } + entry->calling++; + keep = entry->listener->message(entry->listener, ike_sa, + message, incoming); + entry->calling--; + if (!keep) + { + unregister_listener(this, entry, enumerator); break; } } @@ -454,7 +465,7 @@ bus_t *bus_create() this->public.destroy = (void(*)(bus_t*)) destroy; this->listeners = linked_list_create(); - this->mutex = mutex_create(MUTEX_DEFAULT); + this->mutex = mutex_create(MUTEX_RECURSIVE); pthread_key_create(&this->thread_id, NULL); pthread_key_create(&this->thread_sa, NULL); |