@@ -84,6 +84,7 @@ struct UnitEventInfo {
84
84
85
85
struct DoneInitState {
86
86
std::atomic<bool > DoneInit{false };
87
+ unsigned RemainingInitUnits = 0 ; // this is not accessed concurrently.
87
88
};
88
89
89
90
class StoreUnitRepo : public std ::enable_shared_from_this<StoreUnitRepo> {
@@ -94,8 +95,7 @@ class StoreUnitRepo : public std::enable_shared_from_this<StoreUnitRepo> {
94
95
95
96
std::shared_ptr<FilePathWatcher> PathWatcher;
96
97
97
- // This is shared so that it can be safely passed to an asynchronous block.
98
- std::shared_ptr<DoneInitState> DoneInitializingPtr;
98
+ DoneInitState InitializingState;
99
99
dispatch_semaphore_t InitSemaphore;
100
100
101
101
mutable llvm::sys::Mutex StateMtx;
@@ -110,7 +110,6 @@ class StoreUnitRepo : public std::enable_shared_from_this<StoreUnitRepo> {
110
110
Delegate(std::move(Delegate)),
111
111
CanonPathCache(std::move(canonPathCache)) {
112
112
113
- DoneInitializingPtr = std::make_shared<DoneInitState>();
114
113
InitSemaphore = dispatch_semaphore_create (0 );
115
114
}
116
115
~StoreUnitRepo () {
@@ -121,7 +120,11 @@ class StoreUnitRepo : public std::enable_shared_from_this<StoreUnitRepo> {
121
120
function_ref<void (unsigned )> ReportCompleted,
122
121
function_ref<void()> DirectoryDeleted);
123
122
123
+ void setInitialUnitCount (unsigned count);
124
+ void processedInitialUnitCount (unsigned count);
125
+ void finishedUnitInitialization ();
124
126
void waitUntilDoneInitializing ();
127
+
125
128
void purgeStaleData ();
126
129
127
130
std::shared_ptr<UnitMonitor> getUnitMonitor (IDCode unitCode) const ;
@@ -265,9 +268,8 @@ void StoreUnitRepo::onFilesChange(std::vector<UnitEventInfo> evts,
265
268
PathWatcher = std::make_shared<FilePathWatcher>(std::move (pathEventsReceiver));
266
269
}
267
270
268
- if (!DoneInitializingPtr->DoneInit ) {
269
- dispatch_semaphore_signal (InitSemaphore);
270
- DoneInitializingPtr->DoneInit = true ;
271
+ if (!InitializingState.DoneInit ) {
272
+ processedInitialUnitCount (evts.size ());
271
273
}
272
274
}
273
275
@@ -451,8 +453,26 @@ void StoreUnitRepo::purgeStaleData() {
451
453
// IdxStore->purgeStaleRecords(ActiveRecNames);
452
454
}
453
455
456
+ void StoreUnitRepo::setInitialUnitCount (unsigned count) {
457
+ InitializingState.RemainingInitUnits = count;
458
+ }
459
+
460
+ void StoreUnitRepo::processedInitialUnitCount (unsigned count) {
461
+ assert (!InitializingState.DoneInit );
462
+ InitializingState.RemainingInitUnits -= std::min (count, InitializingState.RemainingInitUnits );
463
+ if (InitializingState.RemainingInitUnits == 0 ) {
464
+ finishedUnitInitialization ();
465
+ }
466
+ }
467
+
468
+ void StoreUnitRepo::finishedUnitInitialization () {
469
+ assert (!InitializingState.DoneInit );
470
+ dispatch_semaphore_signal (InitSemaphore);
471
+ InitializingState.DoneInit = true ;
472
+ }
473
+
454
474
void StoreUnitRepo::waitUntilDoneInitializing () {
455
- if (DoneInitializingPtr-> DoneInit )
475
+ if (InitializingState. DoneInit )
456
476
return ;
457
477
dispatch_semaphore_wait (InitSemaphore, DISPATCH_TIME_FOREVER);
458
478
}
@@ -765,6 +785,18 @@ bool IndexDatastoreImpl::init(IndexStoreRef idxStore,
765
785
std::weak_ptr<StoreUnitRepo> WeakUnitRepo = UnitRepo;
766
786
auto eventsDeque = std::make_shared<UnitEventInfoDeque>();
767
787
auto OnUnitsChange = [WeakUnitRepo, Delegate, eventsDeque](IndexStore::UnitEventNotification EventNote) {
788
+ if (EventNote.isInitial ()) {
789
+ auto UnitRepo = WeakUnitRepo.lock ();
790
+ if (!UnitRepo)
791
+ return ;
792
+ size_t evtCount = EventNote.getEventsCount ();
793
+ if (evtCount == 0 ) {
794
+ UnitRepo->finishedUnitInitialization ();
795
+ } else {
796
+ UnitRepo->setInitialUnitCount (evtCount);
797
+ }
798
+ }
799
+
768
800
std::vector<UnitEventInfo> evts;
769
801
for (size_t i = 0 , e = EventNote.getEventsCount (); i != e; ++i) {
770
802
auto evt = EventNote.getEvent (i);
0 commit comments