1919#include "split-index.h"
2020#include "utf8.h"
2121
22+ #ifndef NO_PTHREADS
23+ #include <pthread.h>
24+ #endif
25+
2226/* Mask for the name length in ce_flags in the on-disk index */
2327
2428#define CE_NAMEMASK (0x0fff)
@@ -1398,6 +1402,34 @@ static int verify_hdr(struct cache_header *hdr, unsigned long size)
13981402 return 0 ;
13991403}
14001404
1405+ #ifndef NO_PTHREADS
1406+ /*
1407+ * Require index file to be larger than this threshold before
1408+ * we bother using a thread to verify the SHA.
1409+ * This value was arbitrarily chosen.
1410+ */
1411+ #define VERIFY_HDR_THRESHOLD 10*1024*1024
1412+
1413+ struct verify_hdr_thread_data
1414+ {
1415+ pthread_t thread_id ;
1416+ struct cache_header * hdr ;
1417+ size_t size ;
1418+ int result ;
1419+ };
1420+
1421+ /*
1422+ * A thread proc to run the verify_hdr() computation
1423+ * in a background thread.
1424+ */
1425+ static void * verify_hdr_thread (void * _data )
1426+ {
1427+ struct verify_hdr_thread_data * p = _data ;
1428+ p -> result = verify_hdr (p -> hdr , (unsigned long )p -> size );
1429+ return NULL ;
1430+ }
1431+ #endif
1432+
14011433static int read_index_extension (struct index_state * istate ,
14021434 const char * ext , void * data , unsigned long sz )
14031435{
@@ -1585,6 +1617,9 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist)
15851617 void * mmap ;
15861618 size_t mmap_size ;
15871619 struct strbuf previous_name_buf = STRBUF_INIT , * previous_name ;
1620+ #ifndef NO_PTHREADS
1621+ struct verify_hdr_thread_data verify_hdr_thread_data ;
1622+ #endif
15881623
15891624 if (istate -> initialized )
15901625 return istate -> cache_nr ;
@@ -1611,8 +1646,23 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist)
16111646 close (fd );
16121647
16131648 hdr = mmap ;
1649+ #ifdef NO_PTHREADS
16141650 if (verify_hdr (hdr , mmap_size ) < 0 )
16151651 goto unmap ;
1652+ #else
1653+ if (mmap_size < VERIFY_HDR_THRESHOLD ) {
1654+ if (verify_hdr (hdr , mmap_size ) < 0 )
1655+ goto unmap ;
1656+ } else {
1657+ verify_hdr_thread_data .hdr = hdr ;
1658+ verify_hdr_thread_data .size = mmap_size ;
1659+ verify_hdr_thread_data .result = -1 ;
1660+ if (pthread_create (
1661+ & verify_hdr_thread_data .thread_id , NULL ,
1662+ verify_hdr_thread , & verify_hdr_thread_data ))
1663+ die_errno ("unable to start verify_hdr_thread" );
1664+ }
1665+ #endif
16161666
16171667 hashcpy (istate -> sha1 , (const unsigned char * )hdr + mmap_size - 20 );
16181668 istate -> version = ntohl (hdr -> hdr_version );
@@ -1660,6 +1710,16 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist)
16601710 src_offset += 8 ;
16611711 src_offset += extsize ;
16621712 }
1713+
1714+ #ifndef NO_PTHREADS
1715+ if (mmap_size >= VERIFY_HDR_THRESHOLD ) {
1716+ if (pthread_join (verify_hdr_thread_data .thread_id , NULL ))
1717+ die_errno ("unable to join verify_hdr_thread" );
1718+ if (verify_hdr_thread_data .result < 0 )
1719+ goto unmap ;
1720+ }
1721+ #endif
1722+
16631723 munmap (mmap , mmap_size );
16641724 return istate -> cache_nr ;
16651725
0 commit comments