Segment manipulation in HA sync is thread save

This commit is contained in:
Martin Willi
2010-04-07 13:55:14 +02:00
committed by Martin Willi
parent c573b11c55
commit 3d672d4b0a
+17 -2
View File
@@ -15,6 +15,7 @@
#include "ha_sync_segments.h" #include "ha_sync_segments.h"
#include <utils/mutex.h>
#include <utils/linked_list.h> #include <utils/linked_list.h>
typedef u_int32_t u32; typedef u_int32_t u32;
@@ -36,6 +37,11 @@ struct private_ha_sync_segments_t {
*/ */
ha_sync_segments_t public; ha_sync_segments_t public;
/**
* read/write lock for segment manipulation
*/
rwlock_t *lock;
/** /**
* Init value for jhash * Init value for jhash
*/ */
@@ -121,6 +127,8 @@ static void enable_disable(private_ha_sync_segments_t *this, u_int segment,
enumerator_t *enumerator; enumerator_t *enumerator;
u_int i, limit; u_int i, limit;
this->lock->write_lock(this->lock);
if (segment == 0 || segment <= this->segment_count) if (segment == 0 || segment <= this->segment_count)
{ {
if (segment) if (segment)
@@ -160,6 +168,8 @@ static void enable_disable(private_ha_sync_segments_t *this, u_int segment,
log_segments(this, enable, segment); log_segments(this, enable, segment);
} }
this->lock->unlock(this->lock);
} }
/** /**
@@ -213,10 +223,12 @@ static void resync(private_ha_sync_segments_t *this, u_int segment)
ike_sa_id_t *id; ike_sa_id_t *id;
u_int16_t mask = bit_of(segment); u_int16_t mask = bit_of(segment);
list = linked_list_create();
this->lock->read_lock(this->lock);
if (segment > 0 && segment <= this->segment_count && (this->active & mask)) if (segment > 0 && segment <= this->segment_count && (this->active & mask))
{ {
this->active &= ~mask; this->active &= ~mask;
list = linked_list_create();
DBG1(DBG_CFG, "resyncing HA sync segment %d", segment); DBG1(DBG_CFG, "resyncing HA sync segment %d", segment);
@@ -234,6 +246,8 @@ static void resync(private_ha_sync_segments_t *this, u_int segment)
} }
} }
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
}
this->lock->unlock(this->lock);
while (list->remove_last(list, (void**)&id) == SUCCESS) while (list->remove_last(list, (void**)&id) == SUCCESS)
{ {
@@ -257,13 +271,13 @@ static void resync(private_ha_sync_segments_t *this, u_int segment)
} }
list->destroy(list); list->destroy(list);
} }
}
/** /**
* Implementation of ha_sync_segments_t.destroy. * Implementation of ha_sync_segments_t.destroy.
*/ */
static void destroy(private_ha_sync_segments_t *this) static void destroy(private_ha_sync_segments_t *this)
{ {
this->lock->destroy(this->lock);
free(this); free(this);
} }
@@ -282,6 +296,7 @@ ha_sync_segments_t *ha_sync_segments_create()
this->public.resync = (void(*)(ha_sync_segments_t*, u_int segment))resync; this->public.resync = (void(*)(ha_sync_segments_t*, u_int segment))resync;
this->public.destroy = (void(*)(ha_sync_segments_t*))destroy; this->public.destroy = (void(*)(ha_sync_segments_t*))destroy;
this->lock = rwlock_create(RWLOCK_TYPE_DEFAULT);
this->initval = 0; this->initval = 0;
this->active = 0; this->active = 0;
this->segment_count = lib->settings->get_int(lib->settings, this->segment_count = lib->settings->get_int(lib->settings,