summaryrefslogtreecommitdiff
path: root/src/charon/bus
diff options
context:
space:
mode:
Diffstat (limited to 'src/charon/bus')
-rw-r--r--src/charon/bus/bus.c34
-rw-r--r--src/charon/bus/bus.h16
2 files changed, 19 insertions, 31 deletions
diff --git a/src/charon/bus/bus.c b/src/charon/bus/bus.c
index 5f46cd29e..5fda36925 100644
--- a/src/charon/bus/bus.c
+++ b/src/charon/bus/bus.c
@@ -238,30 +238,13 @@ static active_listener_t *get_active_listener(private_bus_t *this)
return found;
}
-typedef struct cancel_info_t cancel_info_t;
-
-/**
- * cancellation info to cancel a listening operation cleanly
- */
-struct cancel_info_t {
- /**
- * mutex to unlock on cancellation
- */
- pthread_mutex_t *mutex;
-
- /**
- * listener to unregister
- */
- active_listener_t *listener;
-};
-
/**
* disable a listener to cleanly clean up
*/
-static void unregister(cancel_info_t *info)
+static void unregister(active_listener_t *listener)
{
- info->listener->state = UNREGISTERED;
- pthread_mutex_unlock(info->mutex);
+ listener->state = UNREGISTERED;
+ pthread_cond_broadcast(&listener->cond);
}
/**
@@ -272,7 +255,6 @@ static signal_t listen_(private_bus_t *this, level_t *level, int *thread,
{
active_listener_t *listener;
int oldstate;
- cancel_info_t info;
pthread_mutex_lock(&this->mutex);
listener = get_active_listener(this);
@@ -281,13 +263,13 @@ static signal_t listen_(private_bus_t *this, level_t *level, int *thread,
pthread_cond_broadcast(&listener->cond);
/* wait until it has us delivered a signal, and go back to "registered".
* we allow cancellation here, but must cleanly disable the listener. */
- info.mutex = &this->mutex;
- info.listener = listener;
- pthread_cleanup_push((void*)unregister, &info);
+ pthread_cleanup_push((void*)pthread_mutex_unlock, &this->mutex);
+ pthread_cleanup_push((void*)unregister, listener);
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
pthread_cond_wait(&listener->cond, &this->mutex);
pthread_setcancelstate(oldstate, NULL);
pthread_cleanup_pop(0);
+ pthread_cleanup_pop(0);
pthread_mutex_unlock(&this->mutex);
@@ -320,7 +302,7 @@ static void set_listen_state(private_bus_t *this, bool active)
{
listener->state = UNREGISTERED;
/* say hello to signal emitter; we are finished processing the signal */
- pthread_cond_signal(&listener->cond);
+ pthread_cond_broadcast(&listener->cond);
}
pthread_mutex_unlock(&this->mutex);
@@ -390,7 +372,7 @@ static void vsignal(private_bus_t *this, signal_t signal, level_t level,
active_listener->format = format;
va_copy(active_listener->args, args);
active_listener->state = REGISTERED;
- pthread_cond_signal(&active_listener->cond);
+ pthread_cond_broadcast(&active_listener->cond);
}
}
diff --git a/src/charon/bus/bus.h b/src/charon/bus/bus.h
index 4b46c7e82..e54fb1b1b 100644
--- a/src/charon/bus/bus.h
+++ b/src/charon/bus/bus.h
@@ -39,14 +39,18 @@ typedef struct bus_t bus_t;
*
* Signaling is for different purporses. First, it allows debugging via
* "debugging signal messages", sencondly, it allows to follow certain
- * mechanisms currently going on in the daemon. As we are multithreaded,
- * and of multiple transactions are involved, it's not possible to follow
+ * mechanisms currently going on in the daemon. As we are multithreaded,
+ * and multiple transactions are involved, it's not possible to follow
* one connection setup without further infrastructure. These infrastructure
* is provided by the bus and the signals the daemon emits to the bus.
*
* There are different scenarios to follow these signals, but all have
* the same scheme. First, a START signal is emitted to indicate the daemon
- * has started to
+ * has started to do something. After a start signal, a SUCCESS or a FAILED
+ * signal of the same type follows. This allows to track the operation. Any
+ * Debug signal betwee a START and a SUCCESS/FAILED belongs to that operation
+ * if the IKE_SA is the same. The thread may change, as multiple threads
+ * may be involved in a complex scenario.
*
* @ingroup bus
*/
@@ -247,7 +251,9 @@ struct bus_listener_t {
* in receiving event signals registers at the bus. Any signals sent to
* are delivered to all registered listeners.
* To deliver signals to threads, the blocking listen() call may be used
- * to wait for a signal.
+ * to wait for a signal. However, passive listeners should be preferred,
+ * as listening actively requires some synchronization overhead as data
+ * must be passed from the raising thread to the listening thread.
*
* @ingroup bus
*/
@@ -283,7 +289,7 @@ struct bus_t {
* it processes a signal, registration is required. This is done through
* the set_listen_state() method, see below.
*
- * The listen() function is (has) a thread cancellation point, so might
+ * The listen() function is (has) a thread cancellation point, so you might
* want to register cleanup handlers.
*
* @param this bus