diff options
author | Rene Mayrhofer <rene@mayrhofer.eu.org> | 2008-10-29 20:30:44 +0000 |
---|---|---|
committer | Rene Mayrhofer <rene@mayrhofer.eu.org> | 2008-10-29 20:30:44 +0000 |
commit | 74f0bbfc53cb5fa519e4e27ece53735ab51b397c (patch) | |
tree | 0dbab9c835be15577ff05b474b6361bb326d66ce /src/charon/bus | |
parent | 5c1fa2516bda1ccf8eb00178c0beb196c2020a94 (diff) | |
download | vyos-strongswan-74f0bbfc53cb5fa519e4e27ece53735ab51b397c.tar.gz vyos-strongswan-74f0bbfc53cb5fa519e4e27ece53735ab51b397c.zip |
- New upstream release.
Diffstat (limited to 'src/charon/bus')
-rw-r--r-- | src/charon/bus/bus.c | 112 | ||||
-rw-r--r-- | src/charon/bus/bus.h | 74 | ||||
-rw-r--r-- | src/charon/bus/listeners/file_logger.c | 7 | ||||
-rw-r--r-- | src/charon/bus/listeners/sys_logger.c | 7 |
4 files changed, 127 insertions, 73 deletions
diff --git a/src/charon/bus/bus.c b/src/charon/bus/bus.c index 1b12f8735..a102a3984 100644 --- a/src/charon/bus/bus.c +++ b/src/charon/bus/bus.c @@ -12,7 +12,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * $Id: bus.c 3589 2008-03-13 14:14:44Z martin $ + * $Id: bus.c 4198 2008-07-21 14:23:43Z martin $ */ #include "bus.h" @@ -101,6 +101,11 @@ struct entry_t { bool blocker; /** + * are we currently calling this listener + */ + bool calling; + + /** * condvar where active listeners wait */ condvar_t *condvar; @@ -115,6 +120,7 @@ static entry_t *entry_create(bus_listener_t *listener, bool blocker) this->listener = listener; this->blocker = blocker; + this->calling = FALSE; this->condvar = condvar_create(CONDVAR_DEFAULT); return this; @@ -253,58 +259,94 @@ 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; + /** signal specific user data */ + void *user; + /** 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) +{ + va_list args; + + if (entry->calling) + { /* avoid recursive calls */ + return FALSE; + } + entry->calling = TRUE; + va_copy(args, data->args); + if (!entry->listener->signal(entry->listener, data->signal, data->level, + data->thread, data->ike_sa, data->user, data->format, 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); + va_end(args); + entry->calling = FALSE; + return TRUE; } - iterator->destroy(iterator); + va_end(args); + entry->calling = FALSE; + return FALSE; +} + +/** + * Implementation of bus_t.vsignal. + */ +static void vsignal(private_bus_t *this, signal_t signal, level_t level, + void *user, 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.user = user; + 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); } /** * Implementation of bus_t.signal. */ static void signal_(private_bus_t *this, signal_t signal, level_t level, - char* format, ...) + void* data, char* format, ...) { va_list args; va_start(args, format); - vsignal(this, signal, level, format, args); + vsignal(this, signal, level, data, format, args); va_end(args); } @@ -329,8 +371,8 @@ bus_t *bus_create() this->public.remove_listener = (void(*)(bus_t*,bus_listener_t*))remove_listener; this->public.listen = (void(*)(bus_t*, bus_listener_t *listener, job_t *job))listen_; this->public.set_sa = (void(*)(bus_t*,ike_sa_t*))set_sa; - this->public.signal = (void(*)(bus_t*,signal_t,level_t,char*,...))signal_; - this->public.vsignal = (void(*)(bus_t*,signal_t,level_t,char*,va_list))vsignal; + this->public.signal = (void(*)(bus_t*,signal_t,level_t,void*,char*,...))signal_; + this->public.vsignal = (void(*)(bus_t*,signal_t,level_t,void*,char*,va_list))vsignal; this->public.destroy = (void(*)(bus_t*)) destroy; this->listeners = linked_list_create(); diff --git a/src/charon/bus/bus.h b/src/charon/bus/bus.h index 7fa2c42bc..db417064f 100644 --- a/src/charon/bus/bus.h +++ b/src/charon/bus/bus.h @@ -12,7 +12,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * $Id: bus.h 3589 2008-03-13 14:14:44Z martin $ + * $Id: bus.h 4192 2008-07-18 15:51:40Z martin $ */ /** @@ -97,29 +97,29 @@ enum signal_t { IKE_REKEY_FAILED, /** signals for CHILD_SA establishment */ - CHILD_UP_START, - CHILD_UP_SUCCESS, - CHILD_UP_FAILED, + CHD_UP_START, + CHD_UP_SUCCESS, + CHD_UP_FAILED, /** signals for CHILD_SA delete */ - CHILD_DOWN_START, - CHILD_DOWN_SUCCESS, - CHILD_DOWN_FAILED, + CHD_DOWN_START, + CHD_DOWN_SUCCESS, + CHD_DOWN_FAILED, /** signals for CHILD_SA rekeying */ - CHILD_REKEY_START, - CHILD_REKEY_SUCCESS, - CHILD_REKEY_FAILED, + CHD_REKEY_START, + CHD_REKEY_SUCCESS, + CHD_REKEY_FAILED, /** signals for CHILD_SA routing */ - CHILD_ROUTE_START, - CHILD_ROUTE_SUCCESS, - CHILD_ROUTE_FAILED, + CHD_ROUTE_START, + CHD_ROUTE_SUCCESS, + CHD_ROUTE_FAILED, /** signals for CHILD_SA routing */ - CHILD_UNROUTE_START, - CHILD_UNROUTE_SUCCESS, - CHILD_UNROUTE_FAILED, + CHD_UNROUTE_START, + CHD_UNROUTE_SUCCESS, + CHD_UNROUTE_FAILED, SIG_MAX }; @@ -161,16 +161,16 @@ enum level_t { * @param format printf() style format string * @param ... printf() style agument list */ -# define DBG1(sig, format, ...) charon->bus->signal(charon->bus, sig, LEVEL_1, format, ##__VA_ARGS__) +# define DBG1(sig, format, ...) charon->bus->signal(charon->bus, sig, LEVEL_1, NULL, format, ##__VA_ARGS__) #endif /* DEBUG_LEVEL */ #if DEBUG_LEVEL >= 2 -#define DBG2(sig, format, ...) charon->bus->signal(charon->bus, sig, LEVEL_2, format, ##__VA_ARGS__) +#define DBG2(sig, format, ...) charon->bus->signal(charon->bus, sig, LEVEL_2, NULL, format, ##__VA_ARGS__) #endif /* DEBUG_LEVEL */ #if DEBUG_LEVEL >= 3 -#define DBG3(sig, format, ...) charon->bus->signal(charon->bus, sig, LEVEL_3, format, ##__VA_ARGS__) +#define DBG3(sig, format, ...) charon->bus->signal(charon->bus, sig, LEVEL_3, NULL, format, ##__VA_ARGS__) #endif /* DEBUG_LEVEL */ #if DEBUG_LEVEL >= 4 -#define DBG4(sig, format, ...) charon->bus->signal(charon->bus, sig, LEVEL_4, format, ##__VA_ARGS__) +#define DBG4(sig, format, ...) charon->bus->signal(charon->bus, sig, LEVEL_4, NULL, format, ##__VA_ARGS__) #endif /* DEBUG_LEVEL */ #ifndef DBG1 @@ -187,13 +187,22 @@ enum level_t { #endif /* DBG4 */ /** - * Raise a signal for an occured event. + * Raise a signal for an IKE_SA event. * * @param sig signal_t signal description * @param format printf() style format string * @param ... printf() style agument list */ -#define SIG(sig, format, ...) charon->bus->signal(charon->bus, sig, LEVEL_0, format, ##__VA_ARGS__) +#define SIG_IKE(sig, format, ...) charon->bus->signal(charon->bus, IKE_##sig, LEVEL_0, NULL, format, ##__VA_ARGS__) + +/** + * Raise a signal for an IKE event. + * + * @param sig signal_t signal description + * @param format printf() style format string + * @param ... printf() style agument list + */ +#define SIG_CHD(sig, chd, format, ...) charon->bus->signal(charon->bus, CHD_##sig, LEVEL_0, chd, format, ##__VA_ARGS__) /** * Get the type of a signal. @@ -227,20 +236,21 @@ struct bus_listener_t { * a "..." parameters to functions is not (cleanly) possible. * The implementing signal function returns TRUE to stay registered * to the bus, or FALSE to unregister itself. - * You should not call bus_t.signal() inside of a registered listener, - * as it WILL call itself recursively. If you do so, make shure to - * avoid infinite recursion. Watch your stack! + * Calling bus_t.signal() inside of a registered listener is possible, + * but the bus does not invoke listeners recursively. * * @param singal kind of the signal (up, down, rekeyed, ...) * @param level verbosity level of the signal * @param thread ID of the thread raised this signal * @param ike_sa IKE_SA associated to the event + * @param data additional signal specific user data * @param format printf() style format string * @param args vprintf() style va_list argument list " @return TRUE to stay registered, FALSE to unregister */ bool (*signal) (bus_listener_t *this, signal_t signal, level_t level, - int thread, ike_sa_t *ike_sa, char* format, va_list args); + int thread, ike_sa_t *ike_sa, void *data, + char* format, va_list args); }; /** @@ -310,26 +320,26 @@ struct bus_t { * * @param singal kind of the signal (up, down, rekeyed, ...) * @param level verbosity level of the signal + * @param data additional signal specific user data * @param format printf() style format string * @param ... printf() style argument list */ - void (*signal) (bus_t *this, signal_t signal, level_t level, char* format, ...); + void (*signal) (bus_t *this, signal_t signal, level_t level, + void *data, char* format, ...); /** * Send a signal to the bus using va_list arguments. * * 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 data additional signal specific user data * @param format printf() style format string * @param args va_list arguments */ - void (*vsignal) (bus_t *this, signal_t signal, level_t level, char* format, va_list args); + void (*vsignal) (bus_t *this, signal_t signal, level_t level, + void *data, char* format, va_list args); /** * Destroy the signal bus. diff --git a/src/charon/bus/listeners/file_logger.c b/src/charon/bus/listeners/file_logger.c index f89da8529..8a7f66360 100644 --- a/src/charon/bus/listeners/file_logger.c +++ b/src/charon/bus/listeners/file_logger.c @@ -12,7 +12,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * $Id: file_logger.c 3589 2008-03-13 14:14:44Z martin $ + * $Id: file_logger.c 4192 2008-07-18 15:51:40Z martin $ */ #include <stdio.h> @@ -49,7 +49,8 @@ struct private_file_logger_t { * Implementation of bus_listener_t.signal. */ static bool signal_(private_file_logger_t *this, signal_t signal, level_t level, - int thread, ike_sa_t* ike_sa, char *format, va_list args) + int thread, ike_sa_t* ike_sa, void *data, + char *format, va_list args) { if (level <= this->levels[SIG_TYPE(signal)]) { @@ -111,7 +112,7 @@ file_logger_t *file_logger_create(FILE *out) private_file_logger_t *this = malloc_thing(private_file_logger_t); /* public functions */ - this->public.listener.signal = (bool(*)(bus_listener_t*,signal_t,level_t,int,ike_sa_t*,char*,va_list))signal_; + this->public.listener.signal = (bool(*)(bus_listener_t*,signal_t,level_t,int,ike_sa_t*,void*,char*,va_list))signal_; this->public.set_level = (void(*)(file_logger_t*,signal_t,level_t))set_level; this->public.destroy = (void(*)(file_logger_t*))destroy; diff --git a/src/charon/bus/listeners/sys_logger.c b/src/charon/bus/listeners/sys_logger.c index 900fa3aa6..4f5b6fc3b 100644 --- a/src/charon/bus/listeners/sys_logger.c +++ b/src/charon/bus/listeners/sys_logger.c @@ -12,7 +12,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * $Id: sys_logger.c 3589 2008-03-13 14:14:44Z martin $ + * $Id: sys_logger.c 4192 2008-07-18 15:51:40Z martin $ */ #include <stdio.h> @@ -50,7 +50,8 @@ struct private_sys_logger_t { * Implementation of bus_listener_t.signal. */ static bool signal_(private_sys_logger_t *this, signal_t signal, level_t level, - int thread, ike_sa_t* ike_sa, char *format, va_list args) + int thread, ike_sa_t* ike_sa, void *data, + char *format, va_list args) { if (level <= this->levels[SIG_TYPE(signal)]) { @@ -114,7 +115,7 @@ sys_logger_t *sys_logger_create(int facility) private_sys_logger_t *this = malloc_thing(private_sys_logger_t); /* public functions */ - this->public.listener.signal = (bool(*)(bus_listener_t*,signal_t,level_t,int,ike_sa_t*,char*,va_list))signal_; + this->public.listener.signal = (bool(*)(bus_listener_t*,signal_t,level_t,int,ike_sa_t*,void*,char*,va_list))signal_; this->public.set_level = (void(*)(sys_logger_t*,signal_t,level_t))set_level; this->public.destroy = (void(*)(sys_logger_t*))destroy; |