diff options
Diffstat (limited to 'src/charon/bus')
-rw-r--r-- | src/charon/bus/bus.c | 34 | ||||
-rw-r--r-- | src/charon/bus/bus.h | 16 |
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 |