diff options
author | Martin Willi <martin@strongswan.org> | 2008-07-17 11:45:58 +0000 |
---|---|---|
committer | Martin Willi <martin@strongswan.org> | 2008-07-17 11:45:58 +0000 |
commit | bd07b59079d22f75add9889eec6e4f84ce0b2678 (patch) | |
tree | e0e75692e423672872c361c44f7d75ddc88fe0b9 | |
parent | 5353f22ed7a0568f32d880331a6d56f3632ccc8e (diff) | |
download | strongswan-bd07b59079d22f75add9889eec6e4f84ce0b2678.tar.bz2 strongswan-bd07b59079d22f75add9889eec6e4f84ce0b2678.tar.xz |
avoid heap allocation in bus->signal for performance reasons
-rw-r--r-- | src/charon/bus/bus.c | 81 | ||||
-rw-r--r-- | src/charon/bus/bus.h | 4 |
2 files changed, 51 insertions, 34 deletions
diff --git a/src/charon/bus/bus.c b/src/charon/bus/bus.c index 5f813e781..1c57fcc40 100644 --- a/src/charon/bus/bus.c +++ b/src/charon/bus/bus.c @@ -253,46 +253,67 @@ static void set_sa(private_bus_t *this, ike_sa_t *ike_sa) pthread_setspecific(this->thread_sa, ike_sa); } - /** - * Implementation of bus_t.vsignal. + * data associated to a signal, passed to callback */ -static void vsignal(private_bus_t *this, signal_t signal, level_t level, - char* format, va_list args) -{ - iterator_t *iterator; - entry_t *entry; +typedef struct { + /** associated IKE_SA */ ike_sa_t *ike_sa; + /** invoking thread */ long thread; - - this->mutex->lock(this->mutex); - ike_sa = pthread_getspecific(this->thread_sa); - thread = get_thread_number(this); - - iterator = this->listeners->create_iterator(this->listeners, TRUE); - while (iterator->iterate(iterator, (void**)&entry)) + /** signal type */ + signal_t signal; + /** signal level */ + level_t level; + /** format string */ + char *format; + /** argument list */ + va_list args; +} signal_data_t; + +/** + * listener invocation as a list remove callback + */ +static bool signal_cb(entry_t *entry, signal_data_t *data) +{ + if (!entry->listener->signal(entry->listener, data->signal, data->level, + data->thread, data->ike_sa, data->format, data->args)) { - va_list args_copy; - va_copy(args_copy, args); - if (!entry->listener->signal(entry->listener, signal, level, thread, - ike_sa, format, args_copy)) + if (entry->blocker) { - iterator->remove(iterator); - if (entry->blocker) - { - entry->blocker = FALSE; - entry->condvar->signal(entry->condvar); - } - else - { - entry_destroy(entry); - } + entry->blocker = FALSE; + entry->condvar->signal(entry->condvar); + } + else + { + entry_destroy(entry); } - va_end(args_copy); + return TRUE; } - iterator->destroy(iterator); + return FALSE; +} + +/** + * Implementation of bus_t.vsignal. + */ +static void vsignal(private_bus_t *this, signal_t signal, level_t level, + char* format, va_list args) +{ + signal_data_t data; + + data.ike_sa = pthread_getspecific(this->thread_sa); + data.thread = get_thread_number(this); + data.signal = signal; + data.level = level; + data.format = format; + va_copy(data.args, args); + this->mutex->lock(this->mutex); + /* we use the remove() method to invoke all listeners with small overhead */ + this->listeners->remove(this->listeners, &data, (void*)signal_cb); this->mutex->unlock(this->mutex); + + va_end(data.args); } /** diff --git a/src/charon/bus/bus.h b/src/charon/bus/bus.h index 678bf37d4..6ceac4c51 100644 --- a/src/charon/bus/bus.h +++ b/src/charon/bus/bus.h @@ -320,10 +320,6 @@ struct bus_t { * * Same as bus_t.signal(), but uses va_list argument list. * - * @todo Improve performace of vsignal implementation. This method is - * called extensively and therefore shouldn't allocate heap memory or - * do other expensive tasks! - * * @param singal kind of the signal (up, down, rekeyed, ...) * @param level verbosity level of the signal * @param format printf() style format string |