avoid heap allocation in bus->signal for performance reasons
This commit is contained in:
+52
-31
@@ -253,46 +253,67 @@ static void set_sa(private_bus_t *this, ike_sa_t *ike_sa)
|
|||||||
pthread_setspecific(this->thread_sa, ike_sa);
|
pthread_setspecific(this->thread_sa, ike_sa);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* data associated to a signal, passed to callback
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
/** associated IKE_SA */
|
||||||
|
ike_sa_t *ike_sa;
|
||||||
|
/** invoking thread */
|
||||||
|
long thread;
|
||||||
|
/** signal type */
|
||||||
|
signal_t signal;
|
||||||
|
/** signal level */
|
||||||
|
level_t level;
|
||||||
|
/** 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)
|
||||||
|
{
|
||||||
|
if (!entry->listener->signal(entry->listener, data->signal, data->level,
|
||||||
|
data->thread, data->ike_sa, data->format, data->args))
|
||||||
|
{
|
||||||
|
if (entry->blocker)
|
||||||
|
{
|
||||||
|
entry->blocker = FALSE;
|
||||||
|
entry->condvar->signal(entry->condvar);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
entry_destroy(entry);
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of bus_t.vsignal.
|
* Implementation of bus_t.vsignal.
|
||||||
*/
|
*/
|
||||||
static void vsignal(private_bus_t *this, signal_t signal, level_t level,
|
static void vsignal(private_bus_t *this, signal_t signal, level_t level,
|
||||||
char* format, va_list args)
|
char* format, va_list args)
|
||||||
{
|
{
|
||||||
iterator_t *iterator;
|
signal_data_t data;
|
||||||
entry_t *entry;
|
|
||||||
ike_sa_t *ike_sa;
|
data.ike_sa = pthread_getspecific(this->thread_sa);
|
||||||
long thread;
|
data.thread = get_thread_number(this);
|
||||||
|
data.signal = signal;
|
||||||
|
data.level = level;
|
||||||
|
data.format = format;
|
||||||
|
va_copy(data.args, args);
|
||||||
|
|
||||||
this->mutex->lock(this->mutex);
|
this->mutex->lock(this->mutex);
|
||||||
ike_sa = pthread_getspecific(this->thread_sa);
|
/* we use the remove() method to invoke all listeners with small overhead */
|
||||||
thread = get_thread_number(this);
|
this->listeners->remove(this->listeners, &data, (void*)signal_cb);
|
||||||
|
|
||||||
iterator = this->listeners->create_iterator(this->listeners, TRUE);
|
|
||||||
while (iterator->iterate(iterator, (void**)&entry))
|
|
||||||
{
|
|
||||||
va_list args_copy;
|
|
||||||
va_copy(args_copy, args);
|
|
||||||
if (!entry->listener->signal(entry->listener, signal, level, thread,
|
|
||||||
ike_sa, format, args_copy))
|
|
||||||
{
|
|
||||||
iterator->remove(iterator);
|
|
||||||
if (entry->blocker)
|
|
||||||
{
|
|
||||||
entry->blocker = FALSE;
|
|
||||||
entry->condvar->signal(entry->condvar);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
entry_destroy(entry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
va_end(args_copy);
|
|
||||||
}
|
|
||||||
iterator->destroy(iterator);
|
|
||||||
|
|
||||||
this->mutex->unlock(this->mutex);
|
this->mutex->unlock(this->mutex);
|
||||||
|
|
||||||
|
va_end(data.args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -320,10 +320,6 @@ struct bus_t {
|
|||||||
*
|
*
|
||||||
* Same as bus_t.signal(), but uses va_list argument list.
|
* 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 singal kind of the signal (up, down, rekeyed, ...)
|
||||||
* @param level verbosity level of the signal
|
* @param level verbosity level of the signal
|
||||||
* @param format printf() style format string
|
* @param format printf() style format string
|
||||||
|
|||||||
Reference in New Issue
Block a user