@@ -1475,16 +1475,18 @@ void clear_delta_base_cache(void)
14751475static void add_delta_base_cache (struct packed_git * p , off_t base_offset ,
14761476 void * base , unsigned long base_size , enum object_type type )
14771477{
1478- struct delta_base_cache_entry * ent = xmalloc ( sizeof ( * ent )) ;
1478+ struct delta_base_cache_entry * ent ;
14791479 struct list_head * lru , * tmp ;
14801480
14811481 /*
14821482 * Check required to avoid redundant entries when more than one thread
14831483 * is unpacking the same object, in unpack_entry() (since its phases I
14841484 * and III might run concurrently across multiple threads).
14851485 */
1486- if (in_delta_base_cache (p , base_offset ))
1486+ if (in_delta_base_cache (p , base_offset )) {
1487+ free (base );
14871488 return ;
1489+ }
14881490
14891491 delta_base_cached += base_size ;
14901492
@@ -1496,6 +1498,7 @@ static void add_delta_base_cache(struct packed_git *p, off_t base_offset,
14961498 release_delta_base_cache (f );
14971499 }
14981500
1501+ ent = xmalloc (sizeof (* ent ));
14991502 ent -> key .p = p ;
15001503 ent -> key .base_offset = base_offset ;
15011504 ent -> type = type ;
@@ -1776,12 +1779,10 @@ void *unpack_entry(struct repository *r, struct packed_git *p, off_t obj_offset,
17761779 void * external_base = NULL ;
17771780 unsigned long delta_size , base_size = size ;
17781781 int i ;
1782+ off_t base_obj_offset = obj_offset ;
17791783
17801784 data = NULL ;
17811785
1782- if (base )
1783- add_delta_base_cache (p , obj_offset , base , base_size , type );
1784-
17851786 if (!base ) {
17861787 /*
17871788 * We're probably in deep shit, but let's try to fetch
@@ -1819,24 +1820,33 @@ void *unpack_entry(struct repository *r, struct packed_git *p, off_t obj_offset,
18191820 "at offset %" PRIuMAX " from %s" ,
18201821 (uintmax_t )curpos , p -> pack_name );
18211822 data = NULL ;
1822- free ( external_base );
1823- continue ;
1824- }
1823+ } else {
1824+ data = patch_delta ( base , base_size , delta_data ,
1825+ delta_size , & size );
18251826
1826- data = patch_delta (base , base_size ,
1827- delta_data , delta_size ,
1828- & size );
1827+ /*
1828+ * We could not apply the delta; warn the user, but
1829+ * keep going. Our failure will be noticed either in
1830+ * the next iteration of the loop, or if this is the
1831+ * final delta, in the caller when we return NULL.
1832+ * Those code paths will take care of making a more
1833+ * explicit warning and retrying with another copy of
1834+ * the object.
1835+ */
1836+ if (!data )
1837+ error ("failed to apply delta" );
1838+ }
18291839
18301840 /*
1831- * We could not apply the delta; warn the user, but keep going.
1832- * Our failure will be noticed either in the next iteration of
1833- * the loop, or if this is the final delta, in the caller when
1834- * we return NULL. Those code paths will take care of making
1835- * a more explicit warning and retrying with another copy of
1836- * the object .
1841+ * We delay adding `base` to the cache until the end of the loop
1842+ * because unpack_compressed_entry() momentarily releases the
1843+ * obj_read_mutex, giving another thread the chance to access
1844+ * the cache. Therefore, if `base` was already there, this other
1845+ * thread could free() it (e.g. to make space for another entry)
1846+ * before we are done using it .
18371847 */
1838- if (!data )
1839- error ( "failed to apply delta" );
1848+ if (!external_base )
1849+ add_delta_base_cache ( p , base_obj_offset , base , base_size , type );
18401850
18411851 free (delta_data );
18421852 free (external_base );
0 commit comments