Found by Jeff King. Signed-off-by: Nicolas Pitre <nico@xxxxxxx> --- On Mon, 10 Sep 2007, Jeff King wrote: > I think I am seeing something like this: > - thread A gets data_request lock > - thread A unlocks data_provider lock, signaling provider > - thread A blocks getting data_ready lock > - provider allocates work for A, unlocking data_ready to signal A > - provider unlocks data_request lock, ready for next request > - thread B gets data_request lock > - thread B unlocks data_provider lock, signaling provider > - thread B gets data_ready lock, because A still hasn't run yet > - thread B tries to run on bogus data, since provider hasn't actually > allocated any work yet Doh! OK I prefer the following fix as it doesn't need an additional lock. Junio: you might fold this with patch 1/3 if you wish. diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c index 42698d2..af12e45 100644 --- a/builtin-pack-objects.c +++ b/builtin-pack-objects.c @@ -1597,6 +1597,7 @@ static void *threaded_find_deltas(void *arg) data_requester = me; pthread_mutex_unlock(&data_provider); pthread_mutex_lock(&data_ready); + pthread_mutex_unlock(&data_request); if (!me->list_size) return NULL; @@ -1609,7 +1610,7 @@ static void *threaded_find_deltas(void *arg) static void ll_find_deltas(struct object_entry **list, unsigned list_size, int window, int depth, unsigned *processed) { - struct thread_params p[delta_search_threads]; + struct thread_params *target, p[delta_search_threads]; int i, ret; unsigned chunk_size; @@ -1645,17 +1646,17 @@ static void ll_find_deltas(struct object_entry **list, unsigned list_size, sublist_size++; pthread_mutex_lock(&data_provider); - data_requester->list = list; - data_requester->list_size = sublist_size; + target = data_requester; + target->list = list; + target->list_size = sublist_size; pthread_mutex_unlock(&data_ready); list += sublist_size; list_size -= sublist_size; if (!sublist_size) { - pthread_join(data_requester->thread, NULL); + pthread_join(target->thread, NULL); i--; } - pthread_mutex_unlock(&data_request); } while (i); } - To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html