Skip to content

Commit b68eaae

Browse files
authored
Merge pull request #110 from benlangmuir/racy-assert
Fix race in index delegate callback
2 parents 8c593c4 + 79f69b2 commit b68eaae

File tree

2 files changed

+25
-30
lines changed

2 files changed

+25
-30
lines changed

Package.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// swift-tools-version:4.2
1+
// swift-tools-version:5.0
22

33
import PackageDescription
44

@@ -70,7 +70,11 @@ let package = Package(
7070
.target(
7171
name: "IndexStoreDB_Database",
7272
dependencies: ["IndexStoreDB_Core"],
73-
path: "lib/Database"),
73+
path: "lib/Database",
74+
cSettings: [
75+
.define("MDB_USE_POSIX_MUTEX", to: "1"),
76+
.define("MDB_USE_ROBUST", to: "0"),
77+
]),
7478

7579
// Core index types.
7680
.target(

lib/Index/IndexSystem.cpp

Lines changed: 19 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ class AsyncIndexDelegate : public IndexSystemDelegate {
5050
AsyncIndexDelegate(std::shared_ptr<IndexSystemDelegate> Other)
5151
: Others(1, std::move(Other)) {}
5252

53+
~AsyncIndexDelegate() {
54+
_wait(); // Ensure the queue is drained, since we capture `this`.
55+
}
56+
5357
void addDelegate(std::shared_ptr<IndexSystemDelegate> Other) {
5458
Queue.dispatchSync([&] {
5559
if (PendingActions)
@@ -60,36 +64,25 @@ class AsyncIndexDelegate : public IndexSystemDelegate {
6064

6165
private:
6266
virtual void processingAddedPending(unsigned NumActions) override {
63-
PendingActions += NumActions;
64-
65-
if (Others.empty())
66-
return;
67-
auto LocalOthers = this->Others;
68-
Queue.dispatch([LocalOthers, NumActions]{
69-
for (auto &other : LocalOthers)
67+
Queue.dispatch([this, NumActions]{
68+
PendingActions += NumActions;
69+
for (auto &other : Others)
7070
other->processingAddedPending(NumActions);
7171
});
7272
}
7373

7474
virtual void processingCompleted(unsigned NumActions) override {
75-
assert(NumActions <= PendingActions);
76-
PendingActions -= NumActions;
77-
78-
if (Others.empty())
79-
return;
80-
auto LocalOthers = this->Others;
81-
Queue.dispatch([LocalOthers, NumActions]{
82-
for (auto &other : LocalOthers)
75+
Queue.dispatch([this, NumActions]{
76+
assert(NumActions <= PendingActions);
77+
PendingActions -= NumActions;
78+
for (auto &other : Others)
8379
other->processingCompleted(NumActions);
8480
});
8581
}
8682

8783
virtual void processedStoreUnit(StoreUnitInfo unitInfo) override {
88-
if (Others.empty())
89-
return;
90-
auto LocalOthers = this->Others;
91-
Queue.dispatch([LocalOthers, unitInfo]{
92-
for (auto &other : LocalOthers)
84+
Queue.dispatch([this, unitInfo]{
85+
for (auto &other : Others)
9386
other->processedStoreUnit(unitInfo);
9487
});
9588
}
@@ -98,24 +91,22 @@ class AsyncIndexDelegate : public IndexSystemDelegate {
9891
llvm::sys::TimePoint<> outOfDateModTime,
9992
OutOfDateTriggerHintRef hint,
10093
bool synchronous) override {
101-
if (Others.empty())
102-
return;
103-
10494
if (synchronous) {
105-
for (auto &other : Others)
106-
other->unitIsOutOfDate(std::move(unitInfo), outOfDateModTime, hint, true);
95+
Queue.dispatchSync([&]{
96+
for (auto &other : Others)
97+
other->unitIsOutOfDate(std::move(unitInfo), outOfDateModTime, hint, true);
98+
});
10799
return;
108100
}
109101

110-
auto LocalOthers = this->Others;
111102
Queue.dispatch([=]{
112-
for (auto &other : LocalOthers)
103+
for (auto &other : Others)
113104
other->unitIsOutOfDate(std::move(unitInfo), outOfDateModTime, hint, false);
114105
});
115106
}
116107

117108
public:
118-
/// For Testing. Wait for any outstanding async work to finish.
109+
/// Public for Testing. Wait for any outstanding async work to finish.
119110
void _wait() {
120111
Queue.dispatchSync([]{});
121112
}

0 commit comments

Comments
 (0)