@@ -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
@@ -638,7 +648,7 @@ package final actor SemanticIndexManager {
638
648
if registeredTask == preparationTaskID {
639
649
self . inProgressIndexTasks [ fileAndTarget. file] = nil
640
650
}
641
- case nil :
651
+ case . creatingIndexTask , nil :
642
652
break
643
653
}
644
654
}
@@ -686,6 +696,19 @@ package final actor SemanticIndexManager {
686
696
// Sort the targets in topological order so that low-level targets get built before high-level targets, allowing us
687
697
// to index the low-level targets ASAP.
688
698
var filesByTarget : [ BuildTargetIdentifier : [ FileToIndex ] ] = [ : ]
699
+
700
+ // The number of index tasks that don't currently have an in-progress task associated with it.
701
+ // The denominator in the index progress should get incremented by this amount.
702
+ // We don't want to increment the denominator for tasks that already have an index in progress.
703
+ var newIndexTasks = 0
704
+ for file in outOfDateFiles {
705
+ if inProgressIndexTasks [ file] == nil {
706
+ newIndexTasks += 1
707
+ }
708
+ inProgressIndexTasks [ file] = . creatingIndexTask
709
+ }
710
+ indexTasksWereScheduled ( newIndexTasks)
711
+
689
712
for fileToIndex in outOfDateFiles {
690
713
guard let target = await buildSystemManager. canonicalTarget ( for: fileToIndex. mainFile) else {
691
714
logger. error (
@@ -766,10 +789,6 @@ package final actor SemanticIndexManager {
766
789
}
767
790
indexTasks. append ( indexTask)
768
791
769
- // The number of index tasks that don't currently have an in-progress task associated with it.
770
- // The denominator in the index progress should get incremented by this amount.
771
- // We don't want to increment the denominator for tasks that already have an index in progress.
772
- let newIndexTasks = filesToIndex. filter { inProgressIndexTasks [ $0] == nil } . count
773
792
for file in filesToIndex {
774
793
// The state of `inProgressIndexTasks` will get pushed on from `updateIndexStore`.
775
794
// The updates to `inProgressIndexTasks` from `updateIndexStore` cannot race with setting it to
@@ -781,7 +800,6 @@ package final actor SemanticIndexManager {
781
800
indexTask: indexTask
782
801
)
783
802
}
784
- indexTasksWereScheduled ( newIndexTasks)
785
803
}
786
804
let indexTasksImmutable = indexTasks
787
805
0 commit comments