Skip to content

Commit 6a79fcc

Browse files
Take lock over Snapshotter state during callback (#6882)
Co-authored-by: Max <[email protected]>
1 parent 4c74900 commit 6a79fcc

File tree

1 file changed

+27
-21
lines changed

1 file changed

+27
-21
lines changed

src/node/snapshotter.h

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -114,16 +114,27 @@ namespace ccf
114114
std::unique_ptr<ccf::kv::AbstractStore::AbstractSnapshot> snapshot,
115115
uint32_t generation_count)
116116
{
117-
if (pending_snapshots.size() >= max_pending_snapshots_count)
117+
auto snapshot_version = snapshot->get_version();
118+
118119
{
119-
LOG_FAIL_FMT(
120-
"Skipping new snapshot generation as {} snapshots are already "
121-
"pending",
122-
pending_snapshots.size());
123-
return;
124-
}
120+
std::unique_lock<ccf::pal::Mutex> guard(lock);
121+
if (pending_snapshots.size() >= max_pending_snapshots_count)
122+
{
123+
LOG_FAIL_FMT(
124+
"Skipping new snapshot generation as {} snapshots are already "
125+
"pending",
126+
pending_snapshots.size());
127+
return;
128+
}
125129

126-
auto snapshot_version = snapshot->get_version();
130+
// It is possible that the signature following the snapshot evidence is
131+
// scheduled by another thread while the below snapshot evidence
132+
// transaction is committed. To allow for such scenario, the evidence
133+
// seqno is recorded via `record_snapshot_evidence_idx()` on a hook
134+
// rather than here.
135+
pending_snapshots[generation_count] = {};
136+
pending_snapshots[generation_count].version = snapshot_version;
137+
}
127138

128139
auto serialised_snapshot = store->serialise_snapshot(std::move(snapshot));
129140
auto serialised_snapshot_size = serialised_snapshot.size();
@@ -147,14 +158,6 @@ namespace ccf
147158
commit_evidence = commit_evidence_;
148159
};
149160

150-
// It is possible that the signature following the snapshot evidence is
151-
// scheduled by another thread while the below snapshot evidence
152-
// transaction is committed. To allow for such scenario, the evidence
153-
// seqno is recorded via `record_snapshot_evidence_idx()` on a hook rather
154-
// than here.
155-
pending_snapshots[generation_count] = {};
156-
pending_snapshots[generation_count].version = snapshot_version;
157-
158161
auto rc =
159162
tx.commit(cd, false, nullptr, capture_ws_digest_and_commit_evidence);
160163
if (rc != ccf::kv::CommitResult::SUCCESS)
@@ -168,11 +171,14 @@ namespace ccf
168171

169172
auto evidence_version = tx.commit_version();
170173

171-
pending_snapshots[generation_count].commit_evidence = commit_evidence;
172-
pending_snapshots[generation_count].write_set_digest = ws_digest;
173-
pending_snapshots[generation_count].snapshot_digest = cd.value();
174-
pending_snapshots[generation_count].serialised_snapshot =
175-
std::move(serialised_snapshot);
174+
{
175+
std::unique_lock<ccf::pal::Mutex> guard(lock);
176+
pending_snapshots[generation_count].commit_evidence = commit_evidence;
177+
pending_snapshots[generation_count].write_set_digest = ws_digest;
178+
pending_snapshots[generation_count].snapshot_digest = cd.value();
179+
pending_snapshots[generation_count].serialised_snapshot =
180+
std::move(serialised_snapshot);
181+
}
176182

177183
auto to_host = writer_factory.create_writer_to_outside();
178184
RINGBUFFER_WRITE_MESSAGE(

0 commit comments

Comments
 (0)