#include "bus.h"
#include <pthread.h>
+#include <stdint.h>
#include <daemon.h>
#include <utils/mutex.h>
/**
* are we currently calling this listener
*/
- bool calling;
+ int calling;
/**
* condvar where active listeners wait
this->listener = listener;
this->blocker = blocker;
- this->calling = FALSE;
+ this->calling = 0;
this->condvar = condvar_create(CONDVAR_DEFAULT);
return this;
* pthread_self returns large and ugly numbers, use this function
* for logging; these numbers are incremental starting at 1
*/
-static int get_thread_number(private_bus_t *this)
+static u_int get_thread_number(private_bus_t *this)
{
- static long current_num = 0;
- long stored_num;
+ static uintptr_t current_num = 0;
+ uintptr_t stored_num;
- stored_num = (long)pthread_getspecific(this->thread_id);
+ stored_num = (uintptr_t)pthread_getspecific(this->thread_id);
if (stored_num == 0)
{ /* first call of current thread */
pthread_setspecific(this->thread_id, (void*)++current_num);
{ /* avoid recursive calls */
return FALSE;
}
- entry->calling = TRUE;
+ entry->calling++;
va_copy(args, data->args);
if (!entry->listener->log(entry->listener, data->group, data->level,
data->thread, data->ike_sa, data->format, args))
entry_destroy(entry);
}
va_end(args);
- entry->calling = FALSE;
+ entry->calling--;
return TRUE;
}
va_end(args);
- entry->calling = FALSE;
+ entry->calling--;
return FALSE;
}
va_end(args);
}
+static void unregister_listener(private_bus_t *this, entry_t *entry,
+ enumerator_t *enumerator)
+{
+ if (entry->blocker)
+ {
+ entry->blocker = FALSE;
+ entry->condvar->signal(entry->condvar);
+ }
+ else
+ {
+ entry_destroy(entry);
+ }
+ this->listeners->remove_at(this->listeners, enumerator);
+}
+
/**
* Implementation of bus_t.ike_state_change
*/
{
enumerator_t *enumerator;
entry_t *entry;
+ bool keep;
this->mutex->lock(this->mutex);
enumerator = this->listeners->create_enumerator(this->listeners);
while (enumerator->enumerate(enumerator, &entry))
{
- if (entry->listener->ike_state_change &&
- !entry->listener->ike_state_change(entry->listener, ike_sa, state))
+ if (entry->calling || !entry->listener->ike_state_change)
{
- if (entry->blocker)
- {
- entry->blocker = FALSE;
- entry->condvar->signal(entry->condvar);
- }
- else
- {
- entry_destroy(entry);
- }
- this->listeners->remove_at(this->listeners, enumerator);
+ continue;
+ }
+ entry->calling++;
+ keep = entry->listener->ike_state_change(entry->listener, ike_sa, state);
+ entry->calling--;
+ if (!keep)
+ {
+ unregister_listener(this, entry, enumerator);
break;
}
}
enumerator_t *enumerator;
ike_sa_t *ike_sa;
entry_t *entry;
+ bool keep;
ike_sa = pthread_getspecific(this->thread_sa);
enumerator = this->listeners->create_enumerator(this->listeners);
while (enumerator->enumerate(enumerator, &entry))
{
- if (entry->listener->child_state_change &&
- !entry->listener->child_state_change(entry->listener, ike_sa,
- child_sa, state))
+ if (entry->calling || !entry->listener->child_state_change)
{
- if (entry->blocker)
- {
- entry->blocker = FALSE;
- entry->condvar->signal(entry->condvar);
- }
- else
- {
- entry_destroy(entry);
- }
- this->listeners->remove_at(this->listeners, enumerator);
+ continue;
+ }
+ entry->calling++;
+ keep = entry->listener->child_state_change(entry->listener, ike_sa,
+ child_sa, state);
+ entry->calling--;
+ if (!keep)
+ {
+ unregister_listener(this, entry, enumerator);
break;
}
}
enumerator_t *enumerator;
ike_sa_t *ike_sa;
entry_t *entry;
+ bool keep;
ike_sa = pthread_getspecific(this->thread_sa);
enumerator = this->listeners->create_enumerator(this->listeners);
while (enumerator->enumerate(enumerator, &entry))
{
- if (entry->listener->message &&
- !entry->listener->message(entry->listener, ike_sa, message, incoming))
+ if (entry->calling || !entry->listener->message)
{
- if (entry->blocker)
- {
- entry->blocker = FALSE;
- entry->condvar->signal(entry->condvar);
- }
- else
- {
- entry_destroy(entry);
- }
- this->listeners->remove_at(this->listeners, enumerator);
+ continue;
+ }
+ entry->calling++;
+ keep = entry->listener->message(entry->listener, ike_sa,
+ message, incoming);
+ entry->calling--;
+ if (!keep)
+ {
+ unregister_listener(this, entry, enumerator);
break;
}
}
this->public.destroy = (void(*)(bus_t*)) destroy;
this->listeners = linked_list_create();
- this->mutex = mutex_create(MUTEX_DEFAULT);
+ this->mutex = mutex_create(MUTEX_RECURSIVE);
pthread_key_create(&this->thread_id, NULL);
pthread_key_create(&this->thread_sa, NULL);