@@ -55,7 +55,9 @@ typedef struct {
55
55
56
56
enum {
57
57
COMPLETED_STEPS_MUTEX_INITIALIZED = 1 ,
58
- PERFDATA_MUTEX_INITIALIZED = 2
58
+ INDEX_MUTEX_INITIALIZED = 2 ,
59
+ MKPATH_MUTEX_INITIALIZED = 4 ,
60
+ PERFDATA_MUTEX_INITIALIZED = 8
59
61
};
60
62
61
63
typedef struct {
@@ -83,6 +85,8 @@ typedef struct {
83
85
git_strmap * mkdir_map ;
84
86
git_attr_session attr_session ;
85
87
git_mutex completed_steps_mutex ;
88
+ git_mutex index_mutex ;
89
+ git_mutex mkpath_mutex ;
86
90
git_mutex perfdata_mutex ;
87
91
unsigned int mutexes_initialized ;
88
92
} checkout_data ;
@@ -1451,15 +1455,20 @@ static int mkpath2file(
1451
1455
checkout_data * data , const char * path , unsigned int mode )
1452
1456
{
1453
1457
struct stat st ;
1454
- bool remove_existing = should_remove_existing (data );
1455
- unsigned int flags =
1458
+ bool remove_existing ;
1459
+ unsigned int flags ;
1460
+ int error ;
1461
+
1462
+ git_mutex_lock (& data -> mkpath_mutex );
1463
+
1464
+ remove_existing = should_remove_existing (data );
1465
+ flags =
1456
1466
(remove_existing ? MKDIR_REMOVE_EXISTING : MKDIR_NORMAL ) |
1457
1467
GIT_MKDIR_SKIP_LAST ;
1458
- int error ;
1459
1468
1460
1469
if ((error = checkout_mkdir (
1461
1470
data , path , data -> opts .target_directory , mode , flags )) < 0 )
1462
- return error ;
1471
+ goto cleanup ;
1463
1472
1464
1473
if (remove_existing ) {
1465
1474
git_mutex_lock (& data -> perfdata_mutex );
@@ -1476,12 +1485,14 @@ static int mkpath2file(
1476
1485
error = git_futils_rmdir_r (path , NULL , GIT_RMDIR_REMOVE_FILES );
1477
1486
} else if (errno != ENOENT ) {
1478
1487
git_error_set (GIT_ERROR_OS , "failed to stat '%s'" , path );
1479
- return GIT_EEXISTS ;
1488
+ error = GIT_EEXISTS ;
1480
1489
} else {
1481
1490
git_error_clear ();
1482
1491
}
1483
1492
}
1484
1493
1494
+ cleanup :
1495
+ git_mutex_unlock (& data -> mkpath_mutex );
1485
1496
return error ;
1486
1497
}
1487
1498
@@ -1557,12 +1568,19 @@ static int blob_content_to_file(
1557
1568
filter_session .attr_session = & data -> attr_session ;
1558
1569
filter_session .temp_buf = & buffers -> tmp ;
1559
1570
1560
- if (!data -> opts .disable_filters &&
1561
- (error = git_filter_list__load (
1571
+ if (!data -> opts .disable_filters ) {
1572
+ git_mutex_lock (& data -> index_mutex );
1573
+
1574
+ error = git_filter_list__load (
1562
1575
& fl , data -> repo , blob , hint_path ,
1563
- GIT_FILTER_TO_WORKTREE , & filter_session ))) {
1564
- p_close (fd );
1565
- return error ;
1576
+ GIT_FILTER_TO_WORKTREE , & filter_session );
1577
+
1578
+ git_mutex_unlock (& data -> index_mutex );
1579
+
1580
+ if (error ) {
1581
+ p_close (fd );
1582
+ return error ;
1583
+ }
1566
1584
}
1567
1585
1568
1586
/* setup the writer */
@@ -1818,8 +1836,11 @@ static int checkout_blob(
1818
1836
data , & file -> id , fullpath -> ptr , file -> path , file -> mode , & st );
1819
1837
1820
1838
/* update the index unless prevented */
1821
- if (!error && (data -> strategy & GIT_CHECKOUT_DONT_UPDATE_INDEX ) == 0 )
1839
+ if (!error && (data -> strategy & GIT_CHECKOUT_DONT_UPDATE_INDEX ) == 0 ) {
1840
+ git_mutex_lock (& data -> index_mutex );
1822
1841
error = checkout_update_index (data , file , & st );
1842
+ git_mutex_unlock (& data -> index_mutex );
1843
+ }
1823
1844
1824
1845
/* update the submodule data if this was a new .gitmodules file */
1825
1846
if (!error && strcmp (file -> path , ".gitmodules" ) == 0 )
@@ -2412,6 +2433,12 @@ static void checkout_data_clear(checkout_data *data)
2412
2433
if (data -> mutexes_initialized & COMPLETED_STEPS_MUTEX_INITIALIZED )
2413
2434
git_mutex_free (& data -> completed_steps_mutex );
2414
2435
2436
+ if (data -> mutexes_initialized & INDEX_MUTEX_INITIALIZED )
2437
+ git_mutex_free (& data -> index_mutex );
2438
+
2439
+ if (data -> mutexes_initialized & MKPATH_MUTEX_INITIALIZED )
2440
+ git_mutex_free (& data -> mkpath_mutex );
2441
+
2415
2442
if (data -> mutexes_initialized & PERFDATA_MUTEX_INITIALIZED )
2416
2443
git_mutex_free (& data -> perfdata_mutex );
2417
2444
}
@@ -2460,6 +2487,16 @@ static int checkout_data_init(
2460
2487
2461
2488
data -> mutexes_initialized |= COMPLETED_STEPS_MUTEX_INITIALIZED ;
2462
2489
2490
+ if ((error = git_mutex_init (& data -> index_mutex )) < 0 )
2491
+ goto cleanup ;
2492
+
2493
+ data -> mutexes_initialized |= INDEX_MUTEX_INITIALIZED ;
2494
+
2495
+ if ((error = git_mutex_init (& data -> mkpath_mutex )) < 0 )
2496
+ goto cleanup ;
2497
+
2498
+ data -> mutexes_initialized |= MKPATH_MUTEX_INITIALIZED ;
2499
+
2463
2500
if ((error = git_mutex_init (& data -> perfdata_mutex )) < 0 )
2464
2501
goto cleanup ;
2465
2502
0 commit comments