@@ -53,6 +53,11 @@ typedef struct {
5353 git_buf tmp ;
5454} checkout_buffers ;
5555
56+ enum {
57+ COMPLETED_STEPS_MUTEX_INITIALIZED = 1 ,
58+ PERFDATA_MUTEX_INITIALIZED = 2
59+ };
60+
5661typedef struct {
5762 git_repository * repo ;
5863 git_iterator * target ;
@@ -77,6 +82,9 @@ typedef struct {
7782 git_checkout_perfdata perfdata ;
7883 git_strmap * mkdir_map ;
7984 git_attr_session attr_session ;
85+ git_mutex completed_steps_mutex ;
86+ git_mutex perfdata_mutex ;
87+ unsigned int mutexes_initialized ;
8088} checkout_data ;
8189
8290typedef struct {
@@ -1430,9 +1438,11 @@ static int checkout_mkdir(
14301438 error = git_futils_mkdir_relative (
14311439 path , base , mode , flags , & mkdir_opts );
14321440
1441+ git_mutex_lock (& data -> perfdata_mutex );
14331442 data -> perfdata .mkdir_calls += mkdir_opts .perfdata .mkdir_calls ;
14341443 data -> perfdata .stat_calls += mkdir_opts .perfdata .stat_calls ;
14351444 data -> perfdata .chmod_calls += mkdir_opts .perfdata .chmod_calls ;
1445+ git_mutex_unlock (& data -> perfdata_mutex );
14361446
14371447 return error ;
14381448}
@@ -1452,7 +1462,9 @@ static int mkpath2file(
14521462 return error ;
14531463
14541464 if (remove_existing ) {
1465+ git_mutex_lock (& data -> perfdata_mutex );
14551466 data -> perfdata .stat_calls ++ ;
1467+ git_mutex_unlock (& data -> perfdata_mutex );
14561468
14571469 if (p_lstat (path , & st ) == 0 ) {
14581470
@@ -1572,7 +1584,9 @@ static int blob_content_to_file(
15721584 return error ;
15731585
15741586 if (st ) {
1587+ git_mutex_lock (& data -> perfdata_mutex );
15751588 data -> perfdata .stat_calls ++ ;
1589+ git_mutex_unlock (& data -> perfdata_mutex );
15761590
15771591 if ((error = p_stat (path , st )) < 0 ) {
15781592 git_error_set (GIT_ERROR_OS , "failed to stat '%s'" , path );
@@ -1608,7 +1622,9 @@ static int blob_content_to_link(
16081622 }
16091623
16101624 if (!error ) {
1625+ git_mutex_lock (& data -> perfdata_mutex );
16111626 data -> perfdata .stat_calls ++ ;
1627+ git_mutex_unlock (& data -> perfdata_mutex );
16121628
16131629 if ((error = p_lstat (path , st )) < 0 )
16141630 git_error_set (GIT_ERROR_CHECKOUT , "could not stat symlink %s" , path );
@@ -1653,7 +1669,9 @@ static int checkout_submodule_update_index(
16531669 if (checkout_target_fullpath (& fullpath , data , file -> path ) < 0 )
16541670 return -1 ;
16551671
1672+ git_mutex_lock (& data -> perfdata_mutex );
16561673 data -> perfdata .stat_calls ++ ;
1674+ git_mutex_unlock (& data -> perfdata_mutex );
16571675 if (p_stat (fullpath -> ptr , & st ) < 0 ) {
16581676 git_error_set (
16591677 GIT_ERROR_CHECKOUT , "could not stat submodule %s\n" , file -> path );
@@ -1721,7 +1739,9 @@ static int checkout_safe_for_update_only(
17211739{
17221740 struct stat st ;
17231741
1742+ git_mutex_lock (& data -> perfdata_mutex );
17241743 data -> perfdata .stat_calls ++ ;
1744+ git_mutex_unlock (& data -> perfdata_mutex );
17251745
17261746 if (p_lstat (path , & st ) < 0 ) {
17271747 /* if doesn't exist, then no error and no update */
@@ -1834,7 +1854,9 @@ static int checkout_remove_the_old(
18341854 if (error < 0 )
18351855 return error ;
18361856
1857+ git_mutex_lock (& data -> completed_steps_mutex );
18371858 data -> completed_steps ++ ;
1859+ git_mutex_unlock (& data -> completed_steps_mutex );
18381860 report_progress (data , delta -> old_file .path );
18391861
18401862 if ((actions [i ] & CHECKOUT_ACTION__UPDATE_BLOB ) == 0 &&
@@ -1851,7 +1873,10 @@ static int checkout_remove_the_old(
18511873 if (error < 0 )
18521874 return error ;
18531875
1876+
1877+ git_mutex_lock (& data -> completed_steps_mutex );
18541878 data -> completed_steps ++ ;
1879+ git_mutex_unlock (& data -> completed_steps_mutex );
18551880 report_progress (data , str );
18561881
18571882 if ((data -> strategy & GIT_CHECKOUT_DONT_UPDATE_INDEX ) == 0 &&
@@ -1889,7 +1914,9 @@ static int checkout_create_the_new_perform(
18891914 if ((error = checkout_blob (data , & delta -> new_file )) < 0 )
18901915 return error ;
18911916
1917+ git_mutex_lock (& data -> completed_steps_mutex );
18921918 data -> completed_steps ++ ;
1919+ git_mutex_unlock (& data -> completed_steps_mutex );
18931920 report_progress (data , delta -> new_file .path );
18941921 }
18951922
@@ -1932,7 +1959,9 @@ static int checkout_create_submodules(
19321959 if (error < 0 )
19331960 return error ;
19341961
1962+ git_mutex_lock (& data -> completed_steps_mutex );
19351963 data -> completed_steps ++ ;
1964+ git_mutex_unlock (& data -> completed_steps_mutex );
19361965 report_progress (data , delta -> new_file .path );
19371966 }
19381967 }
@@ -2280,7 +2309,9 @@ static int checkout_create_conflicts(checkout_data *data)
22802309 if (error )
22812310 break ;
22822311
2312+ git_mutex_lock (& data -> completed_steps_mutex );
22832313 data -> completed_steps ++ ;
2314+ git_mutex_unlock (& data -> completed_steps_mutex );
22842315 report_progress (data ,
22852316 conflict -> ours ? conflict -> ours -> path :
22862317 (conflict -> theirs ? conflict -> theirs -> path : conflict -> ancestor -> path ));
@@ -2298,7 +2329,9 @@ static int checkout_remove_conflicts(checkout_data *data)
22982329 if (git_index_conflict_remove (data -> index , conflict ) < 0 )
22992330 return -1 ;
23002331
2332+ git_mutex_lock (& data -> completed_steps_mutex );
23012333 data -> completed_steps ++ ;
2334+ git_mutex_unlock (& data -> completed_steps_mutex );
23022335 }
23032336
23042337 return 0 ;
@@ -2375,6 +2408,12 @@ static void checkout_data_clear(checkout_data *data)
23752408 data -> mkdir_map = NULL ;
23762409
23772410 git_attr_session__free (& data -> attr_session );
2411+
2412+ if (data -> mutexes_initialized & COMPLETED_STEPS_MUTEX_INITIALIZED )
2413+ git_mutex_free (& data -> completed_steps_mutex );
2414+
2415+ if (data -> mutexes_initialized & PERFDATA_MUTEX_INITIALIZED )
2416+ git_mutex_free (& data -> perfdata_mutex );
23782417}
23792418
23802419static int validate_target_directory (checkout_data * data )
@@ -2416,6 +2455,16 @@ static int checkout_data_init(
24162455 data -> repo = repo ;
24172456 data -> target = target ;
24182457
2458+ if ((error = git_mutex_init (& data -> completed_steps_mutex )) < 0 )
2459+ goto cleanup ;
2460+
2461+ data -> mutexes_initialized |= COMPLETED_STEPS_MUTEX_INITIALIZED ;
2462+
2463+ if ((error = git_mutex_init (& data -> perfdata_mutex )) < 0 )
2464+ goto cleanup ;
2465+
2466+ data -> mutexes_initialized |= PERFDATA_MUTEX_INITIALIZED ;
2467+
24192468 GIT_ERROR_CHECK_VERSION (
24202469 proposed , GIT_CHECKOUT_OPTIONS_VERSION , "git_checkout_options" );
24212470
0 commit comments