@@ -53,6 +53,14 @@ private struct OpaqueQueuedIndexTask: Equatable {
53
53
}
54
54
55
55
private enum InProgressIndexStore {
56
+ /// We know that we need to index the file but and are currently gathering all information to create the `indexTask`
57
+ /// that will index it.
58
+ ///
59
+ /// This is needed to avoid the following race: We request indexing of file A. Getting the canonical target for A
60
+ /// takes a bit and before that finishes, we request another index of A. In this case, we don't want to kick off
61
+ /// two tasks to update the index store.
62
+ case creatingIndexTask
63
+
56
64
/// We are waiting for preparation of the file's target to be scheduled. The next step is that we wait for
57
65
/// preparation to finish before we can update the index store for this file.
58
66
///
@@ -223,7 +231,7 @@ package final actor SemanticIndexManager {
223
231
}
224
232
let indexTasks = inProgressIndexTasks. mapValues { status in
225
233
switch status {
226
- case . waitingForPreparation, . preparing:
234
+ case . creatingIndexTask , . waitingForPreparation, . preparing:
227
235
return IndexTaskStatus . scheduled
228
236
case . updatingIndexStore( updateIndexStoreTask: let updateIndexStoreTask, indexTask: _) :
229
237
return updateIndexStoreTask. isExecuting ? IndexTaskStatus . executing : IndexTaskStatus . scheduled
@@ -334,6 +342,8 @@ package final actor SemanticIndexManager {
334
342
await withTaskGroup ( of: Void . self) { taskGroup in
335
343
for (_, status) in inProgressIndexTasks {
336
344
switch status {
345
+ case . creatingIndexTask:
346
+ break
337
347
case . waitingForPreparation( preparationTaskID: _, indexTask: let indexTask) ,
338
348
. preparing( preparationTaskID: _, indexTask: let indexTask) ,
339
349
. updatingIndexStore( updateIndexStoreTask: _, indexTask: let indexTask) :
@@ -459,7 +469,7 @@ package final actor SemanticIndexManager {
459
469
}
460
470
. filter {
461
471
switch inProgressIndexTasks [ $0] {
462
- case . waitingForPreparation:
472
+ case . waitingForPreparation, . creatingIndexTask :
463
473
return false
464
474
default :
465
475
return true
@@ -650,7 +660,7 @@ package final actor SemanticIndexManager {
650
660
if registeredTask == preparationTaskID {
651
661
self . inProgressIndexTasks [ fileAndTarget. file] = nil
652
662
}
653
- case nil :
663
+ case . creatingIndexTask , nil :
654
664
break
655
665
}
656
666
}
@@ -698,6 +708,19 @@ package final actor SemanticIndexManager {
698
708
// Sort the targets in topological order so that low-level targets get built before high-level targets, allowing us
699
709
// to index the low-level targets ASAP.
700
710
var filesByTarget : [ BuildTargetIdentifier : [ FileToIndex ] ] = [ : ]
711
+
712
+ // The number of index tasks that don't currently have an in-progress task associated with it.
713
+ // The denominator in the index progress should get incremented by this amount.
714
+ // We don't want to increment the denominator for tasks that already have an index in progress.
715
+ var newIndexTasks = 0
716
+ for file in outOfDateFiles {
717
+ if inProgressIndexTasks [ file] == nil {
718
+ newIndexTasks += 1
719
+ }
720
+ inProgressIndexTasks [ file] = . creatingIndexTask
721
+ }
722
+ indexTasksWereScheduled ( newIndexTasks)
723
+
701
724
for fileToIndex in outOfDateFiles {
702
725
guard let target = await buildSystemManager. canonicalTarget ( for: fileToIndex. mainFile) else {
703
726
logger. error (
@@ -778,10 +801,6 @@ package final actor SemanticIndexManager {
778
801
}
779
802
indexTasks. append ( indexTask)
780
803
781
- // The number of index tasks that don't currently have an in-progress task associated with it.
782
- // The denominator in the index progress should get incremented by this amount.
783
- // We don't want to increment the denominator for tasks that already have an index in progress.
784
- let newIndexTasks = filesToIndex. filter { inProgressIndexTasks [ $0] == nil } . count
785
804
for file in filesToIndex {
786
805
// The state of `inProgressIndexTasks` will get pushed on from `updateIndexStore`.
787
806
// The updates to `inProgressIndexTasks` from `updateIndexStore` cannot race with setting it to
@@ -793,7 +812,6 @@ package final actor SemanticIndexManager {
793
812
indexTask: indexTask
794
813
)
795
814
}
796
- indexTasksWereScheduled ( newIndexTasks)
797
815
}
798
816
let indexTasksImmutable = indexTasks
799
817
0 commit comments