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)
@@ -1400,6 +1404,34 @@ static int verify_hdr(struct cache_header *hdr, unsigned long size)
14001404 return 0 ;
14011405}
14021406
1407+ #ifndef NO_PTHREADS
1408+ /*
1409+ * Require index file to be larger than this threshold before
1410+ * we bother using a thread to verify the SHA.
1411+ * This value was arbitrarily chosen.
1412+ */
1413+ #define VERIFY_HDR_THRESHOLD 10*1024*1024
1414+
1415+ struct verify_hdr_thread_data
1416+ {
1417+ pthread_t thread_id ;
1418+ struct cache_header * hdr ;
1419+ size_t size ;
1420+ int result ;
1421+ };
1422+
1423+ /*
1424+ * A thread proc to run the verify_hdr() computation
1425+ * in a background thread.
1426+ */
1427+ static void * verify_hdr_thread (void * _data )
1428+ {
1429+ struct verify_hdr_thread_data * p = _data ;
1430+ p -> result = verify_hdr (p -> hdr , (unsigned long )p -> size );
1431+ return NULL ;
1432+ }
1433+ #endif
1434+
14031435static int read_index_extension (struct index_state * istate ,
14041436 const char * ext , void * data , unsigned long sz )
14051437{
@@ -1588,6 +1620,9 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist)
15881620 void * mmap ;
15891621 size_t mmap_size ;
15901622 struct strbuf previous_name_buf = STRBUF_INIT , * previous_name ;
1623+ #ifndef NO_PTHREADS
1624+ struct verify_hdr_thread_data verify_hdr_thread_data ;
1625+ #endif
15911626
15921627 if (istate -> initialized )
15931628 return istate -> cache_nr ;
@@ -1614,8 +1649,23 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist)
16141649 close (fd );
16151650
16161651 hdr = mmap ;
1652+ #ifdef NO_PTHREADS
16171653 if (verify_hdr (hdr , mmap_size ) < 0 )
16181654 goto unmap ;
1655+ #else
1656+ if (mmap_size < VERIFY_HDR_THRESHOLD ) {
1657+ if (verify_hdr (hdr , mmap_size ) < 0 )
1658+ goto unmap ;
1659+ } else {
1660+ verify_hdr_thread_data .hdr = hdr ;
1661+ verify_hdr_thread_data .size = mmap_size ;
1662+ verify_hdr_thread_data .result = -1 ;
1663+ if (pthread_create (
1664+ & verify_hdr_thread_data .thread_id , NULL ,
1665+ verify_hdr_thread , & verify_hdr_thread_data ))
1666+ die_errno ("unable to start verify_hdr_thread" );
1667+ }
1668+ #endif
16191669
16201670 hashcpy (istate -> sha1 , (const unsigned char * )hdr + mmap_size - 20 );
16211671 istate -> version = ntohl (hdr -> hdr_version );
@@ -1663,6 +1713,16 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist)
16631713 src_offset += 8 ;
16641714 src_offset += extsize ;
16651715 }
1716+
1717+ #ifndef NO_PTHREADS
1718+ if (mmap_size >= VERIFY_HDR_THRESHOLD ) {
1719+ if (pthread_join (verify_hdr_thread_data .thread_id , NULL ))
1720+ die_errno ("unable to join verify_hdr_thread" );
1721+ if (verify_hdr_thread_data .result < 0 )
1722+ goto unmap ;
1723+ }
1724+ #endif
1725+
16661726 munmap (mmap , mmap_size );
16671727 return istate -> cache_nr ;
16681728
0 commit comments