From 0c8386b95dfa444660cdab2df03e3a6f0e175450 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 20 Sep 2013 14:25:54 +0200 Subject: partial_sim: Fix racy locking --- src/partial_sim.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'src/partial_sim.c') diff --git a/src/partial_sim.c b/src/partial_sim.c index 74b1d734..bbdc1550 100644 --- a/src/partial_sim.c +++ b/src/partial_sim.c @@ -116,15 +116,21 @@ static void calculate_partials(Crystal *cr, if ( rfull == NULL ) { if ( random_intensities ) { - /* The full reflection is immutable (in this - * program) once created, but creating it must - * be an atomic operation. So do the whole - * thing under lock. */ pthread_rwlock_wrlock(full_lock); - rfull = add_refl(full, h, k, l); - If = fabs(gaussian_noise(0.0, full_stddev)); - set_intensity(rfull, If); - set_redundancy(rfull, 1); + + /* In the gap between the unlock and the wrlock, + * the reflection might have been created by + * another thread. So, we must check again */ + rfull = find_refl(full, h, k, l); + if ( rfull == NULL ) { + rfull = add_refl(full, h, k, l); + If = fabs(gaussian_noise(0.0, + full_stddev)); + set_intensity(rfull, If); + set_redundancy(rfull, 1); + } else { + If = get_intensity(rfull); + } pthread_rwlock_unlock(full_lock); } else { -- cgit v1.2.3