From d6656f11e48d9b545738d5f40e59f3c3dd90ef97 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Fri, 23 Dec 2011 10:38:10 +0100 Subject: [PATCH] Fixed flush() method of trap_manager_t. A segmentation fault could have happened during destruction of the trap manager after calling flush(). --- src/libcharon/sa/trap_manager.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/libcharon/sa/trap_manager.c b/src/libcharon/sa/trap_manager.c index bf9f8432c..c7a8a6e0c 100644 --- a/src/libcharon/sa/trap_manager.c +++ b/src/libcharon/sa/trap_manager.c @@ -353,15 +353,21 @@ METHOD(listener_t, child_state_change, bool, METHOD(trap_manager_t, flush, void, private_trap_manager_t *this) { - this->traps->invoke_function(this->traps, (void*)destroy_entry); + linked_list_t *traps; + /* since destroying the CHILD_SA results in events which require a read + * lock we cannot destroy the list while holding the write lock */ + this->lock->write_lock(this->lock); + traps = this->traps; + this->traps = linked_list_create(); + this->lock->unlock(this->lock); + traps->destroy_function(traps, (void*)destroy_entry); } METHOD(trap_manager_t, destroy, void, private_trap_manager_t *this) { charon->bus->remove_listener(charon->bus, &this->listener.listener); - this->traps->invoke_function(this->traps, (void*)destroy_entry); - this->traps->destroy(this->traps); + this->traps->destroy_function(this->traps, (void*)destroy_entry); this->lock->destroy(this->lock); free(this); }