#include <daemon.h>
#include <threading/mutex.h>
#include <threading/rwlock.h>
+#include <threading/rwlock_condvar.h>
#include <collections/linked_list.h>
+#define INSTALL_DISABLED ((u_int)~0)
+
typedef struct private_trap_manager_t private_trap_manager_t;
typedef struct trap_listener_t trap_listener_t;
*/
mutex_t *mutex;
+ /**
+ * number of threads currently installing trap policies, or INSTALL_DISABLED
+ */
+ u_int installing;
+
+ /**
+ * condvar to signal trap policy installation
+ */
+ rwlock_condvar_t *condvar;
+
/**
* Whether to ignore traffic selectors from acquires
*/
}
this->lock->write_lock(this->lock);
+ if (this->installing == INSTALL_DISABLED)
+ { /* flush() has been called */
+ this->lock->unlock(this->lock);
+ return 0;
+ }
enumerator = this->traps->create_enumerator(this->traps);
while (enumerator->enumerate(enumerator, &entry))
{
.peer_cfg = peer->get_ref(peer),
);
this->traps->insert_first(this->traps, entry);
+ this->installing++;
/* don't hold lock while creating CHILD_SA and installing policies */
this->lock->unlock(this->lock);
{
destroy_entry(found);
}
+ this->lock->write_lock(this->lock);
+ /* do this at the end, so entries created temporarily are also destroyed */
+ this->installing--;
+ this->condvar->signal(this->condvar);
+ this->lock->unlock(this->lock);
return reqid;
}
private_trap_manager_t *this)
{
this->lock->write_lock(this->lock);
+ while (this->installing)
+ {
+ this->condvar->wait(this->condvar, this->lock);
+ }
this->traps->destroy_function(this->traps, (void*)destroy_entry);
this->traps = linked_list_create();
+ this->installing = INSTALL_DISABLED;
this->lock->unlock(this->lock);
}
charon->bus->remove_listener(charon->bus, &this->listener.listener);
this->traps->destroy_function(this->traps, (void*)destroy_entry);
this->acquires->destroy_function(this->acquires, (void*)destroy_acquire);
+ this->condvar->destroy(this->condvar);
this->mutex->destroy(this->mutex);
this->lock->destroy(this->lock);
free(this);
.acquires = linked_list_create(),
.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
.lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
+ .condvar = rwlock_condvar_create(),
.ignore_acquire_ts = lib->settings->get_bool(lib->settings,
"%s.ignore_acquire_ts", FALSE, lib->ns),
);