summaryrefslogtreecommitdiff
path: root/src/charon/bus
diff options
context:
space:
mode:
authorRene Mayrhofer <rene@mayrhofer.eu.org>2008-10-29 20:30:44 +0000
committerRene Mayrhofer <rene@mayrhofer.eu.org>2008-10-29 20:30:44 +0000
commit74f0bbfc53cb5fa519e4e27ece53735ab51b397c (patch)
tree0dbab9c835be15577ff05b474b6361bb326d66ce /src/charon/bus
parent5c1fa2516bda1ccf8eb00178c0beb196c2020a94 (diff)
downloadvyos-strongswan-74f0bbfc53cb5fa519e4e27ece53735ab51b397c.tar.gz
vyos-strongswan-74f0bbfc53cb5fa519e4e27ece53735ab51b397c.zip
- New upstream release.
Diffstat (limited to 'src/charon/bus')
-rw-r--r--src/charon/bus/bus.c112
-rw-r--r--src/charon/bus/bus.h74
-rw-r--r--src/charon/bus/listeners/file_logger.c7
-rw-r--r--src/charon/bus/listeners/sys_logger.c7
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;