From: Johannes Schindelin <johannes.schindelin@xxxxxx> In 9ac3f0e5b3e4 (pack-objects: fix performance issues on packing large deltas, 2018-07-22), a mutex was introduced that is used to guard the call to set the delta size. This commit even added code to initialize it, but at an incorrect spot: in `init_threaded_search()`, while the call to `oe_set_delta_size()` (and hence to `packing_data_lock()`) can happen in the call chain `check_object()` <- `get_object_details()` <- `prepare_pack()` <- `cmd_pack_objects()`, which is long before the `prepare_pack()` function calls `ll_find_deltas()` (which initializes the threaded search). Another tell-tale that the mutex was initialized in an incorrect spot is that the function to initialize it lives in builtin/, while the code that uses the mutex is defined in a libgit.a header file. Let's use a more appropriate function: `prepare_packing_data()`, which not only lives in libgit.a, but *has* to be called before the `packing_data` struct is used that contains that mutex. This fixes https://github.com/git-for-windows/git/issues/1839. Signed-off-by: Johannes Schindelin <johannes.schindelin@xxxxxx> --- builtin/pack-objects.c | 1 - pack-objects.c | 3 +++ t/t5321-pack-large-objects.sh | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index e6316d294d..e752cf9c7a 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -2363,7 +2363,6 @@ static void init_threaded_search(void) pthread_mutex_init(&cache_mutex, NULL); pthread_mutex_init(&progress_mutex, NULL); pthread_cond_init(&progress_cond, NULL); - pthread_mutex_init(&to_pack.lock, NULL); old_try_to_free_routine = set_try_to_free_routine(try_to_free_from_threads); } diff --git a/pack-objects.c b/pack-objects.c index 7e624c30eb..b6cdbb0166 100644 --- a/pack-objects.c +++ b/pack-objects.c @@ -148,6 +148,9 @@ void prepare_packing_data(struct packing_data *pdata) 1U << OE_SIZE_BITS); pdata->oe_delta_size_limit = git_env_ulong("GIT_TEST_OE_DELTA_SIZE", 1UL << OE_DELTA_SIZE_BITS); +#ifndef NO_PTHREADS + pthread_mutex_init(&pdata->lock, NULL); +#endif } struct object_entry *packlist_alloc(struct packing_data *pdata, diff --git a/t/t5321-pack-large-objects.sh b/t/t5321-pack-large-objects.sh index c36c66fbb4..a75eab87d3 100755 --- a/t/t5321-pack-large-objects.sh +++ b/t/t5321-pack-large-objects.sh @@ -24,7 +24,7 @@ test_expect_success 'setup' ' git index-pack --stdin <ab.pack ' -test_expect_failure 'repack large deltas' ' +test_expect_success 'repack large deltas' ' printf "%s\\n" $A $B | GIT_TEST_OE_DELTA_SIZE=2 git pack-objects tmp-pack ' -- gitgitgadget