Skip to content

Commit 3c0fe32

Browse files
authored
Merge pull request #20 from akyrtzi/waitUntilDoneInitializin-fix
[IndexDatastore] Ensure `IndexDatastore::waitUntilDoneInitializing()` works properly
2 parents 81a6700 + f1147ad commit 3c0fe32

File tree

1 file changed

+39
-7
lines changed

1 file changed

+39
-7
lines changed

lib/Index/IndexDatastore.cpp

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ struct UnitEventInfo {
8484

8585
struct DoneInitState {
8686
std::atomic<bool> DoneInit{false};
87+
unsigned RemainingInitUnits = 0; // this is not accessed concurrently.
8788
};
8889

8990
class StoreUnitRepo : public std::enable_shared_from_this<StoreUnitRepo> {
@@ -94,8 +95,7 @@ class StoreUnitRepo : public std::enable_shared_from_this<StoreUnitRepo> {
9495

9596
std::shared_ptr<FilePathWatcher> PathWatcher;
9697

97-
// This is shared so that it can be safely passed to an asynchronous block.
98-
std::shared_ptr<DoneInitState> DoneInitializingPtr;
98+
DoneInitState InitializingState;
9999
dispatch_semaphore_t InitSemaphore;
100100

101101
mutable llvm::sys::Mutex StateMtx;
@@ -110,7 +110,6 @@ class StoreUnitRepo : public std::enable_shared_from_this<StoreUnitRepo> {
110110
Delegate(std::move(Delegate)),
111111
CanonPathCache(std::move(canonPathCache)) {
112112

113-
DoneInitializingPtr = std::make_shared<DoneInitState>();
114113
InitSemaphore = dispatch_semaphore_create(0);
115114
}
116115
~StoreUnitRepo() {
@@ -121,7 +120,11 @@ class StoreUnitRepo : public std::enable_shared_from_this<StoreUnitRepo> {
121120
function_ref<void(unsigned)> ReportCompleted,
122121
function_ref<void()> DirectoryDeleted);
123122

123+
void setInitialUnitCount(unsigned count);
124+
void processedInitialUnitCount(unsigned count);
125+
void finishedUnitInitialization();
124126
void waitUntilDoneInitializing();
127+
125128
void purgeStaleData();
126129

127130
std::shared_ptr<UnitMonitor> getUnitMonitor(IDCode unitCode) const;
@@ -265,9 +268,8 @@ void StoreUnitRepo::onFilesChange(std::vector<UnitEventInfo> evts,
265268
PathWatcher = std::make_shared<FilePathWatcher>(std::move(pathEventsReceiver));
266269
}
267270

268-
if (!DoneInitializingPtr->DoneInit) {
269-
dispatch_semaphore_signal(InitSemaphore);
270-
DoneInitializingPtr->DoneInit = true;
271+
if (!InitializingState.DoneInit) {
272+
processedInitialUnitCount(evts.size());
271273
}
272274
}
273275

@@ -451,8 +453,26 @@ void StoreUnitRepo::purgeStaleData() {
451453
// IdxStore->purgeStaleRecords(ActiveRecNames);
452454
}
453455

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+
454474
void StoreUnitRepo::waitUntilDoneInitializing() {
455-
if (DoneInitializingPtr->DoneInit)
475+
if (InitializingState.DoneInit)
456476
return;
457477
dispatch_semaphore_wait(InitSemaphore, DISPATCH_TIME_FOREVER);
458478
}
@@ -765,6 +785,18 @@ bool IndexDatastoreImpl::init(IndexStoreRef idxStore,
765785
std::weak_ptr<StoreUnitRepo> WeakUnitRepo = UnitRepo;
766786
auto eventsDeque = std::make_shared<UnitEventInfoDeque>();
767787
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+
768800
std::vector<UnitEventInfo> evts;
769801
for (size_t i = 0, e = EventNote.getEventsCount(); i != e; ++i) {
770802
auto evt = EventNote.getEvent(i);

0 commit comments

Comments
 (0)