aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2020-11-19 20:03:06 +0100
committerGitHub <noreply@github.com>2020-11-19 20:03:06 +0100
commitbc4df3394db7115413c7cf6a94b44a3749b79ef7 (patch)
tree5e865ee17c08e18bb91f769a36427dbcc1d6185f
parent79aa7d95183cbe6c0d786965f0dbff414fd1aa67 (diff)
parent2113ae2d856a208350ccbafdc19e8dda322515b8 (diff)
Merge pull request #4269 from obsidiansystems/sync-hash-derivation-modulo-cache
Make drv hash modulo memo table thread-safe
-rw-r--r--src/libexpr/primops.cc7
-rw-r--r--src/libstore/derivations.cc27
-rw-r--r--src/libstore/derivations.hh3
3 files changed, 21 insertions, 16 deletions
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index 236433ef1..41f06c219 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -1132,9 +1132,10 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
However, we don't bother doing this for floating CA derivations because
their "hash modulo" is indeterminate until built. */
- if (drv.type() != DerivationType::CAFloating)
- drvHashes.insert_or_assign(drvPath,
- hashDerivationModulo(*state.store, Derivation(drv), false));
+ if (drv.type() != DerivationType::CAFloating) {
+ auto h = hashDerivationModulo(*state.store, Derivation(drv), false);
+ drvHashes.lock()->insert_or_assign(drvPath, h);
+ }
state.mkAttrs(v, 1 + drv.outputs.size());
mkString(*state.allocAttr(v, state.sDrvPath), drvPathS, {"=" + drvPathS});
diff --git a/src/libstore/derivations.cc b/src/libstore/derivations.cc
index 106ec5daa..231ca26c2 100644
--- a/src/libstore/derivations.cc
+++ b/src/libstore/derivations.cc
@@ -451,7 +451,7 @@ DerivationType BasicDerivation::type() const
}
-DrvHashes drvHashes;
+Sync<DrvHashes> drvHashes;
/* pathDerivationModulo and hashDerivationModulo are mutually recursive
*/
@@ -459,19 +459,22 @@ DrvHashes drvHashes;
/* Look up the derivation by value and memoize the
`hashDerivationModulo` call.
*/
-static const DrvHashModulo & pathDerivationModulo(Store & store, const StorePath & drvPath)
+static const DrvHashModulo pathDerivationModulo(Store & store, const StorePath & drvPath)
{
- auto h = drvHashes.find(drvPath);
- if (h == drvHashes.end()) {
- // Cache it
- h = drvHashes.insert_or_assign(
- drvPath,
- hashDerivationModulo(
- store,
- store.readInvalidDerivation(drvPath),
- false)).first;
+ {
+ auto hashes = drvHashes.lock();
+ auto h = hashes->find(drvPath);
+ if (h != hashes->end()) {
+ return h->second;
+ }
}
- return h->second;
+ auto h = hashDerivationModulo(
+ store,
+ store.readInvalidDerivation(drvPath),
+ false);
+ // Cache it
+ drvHashes.lock()->insert_or_assign(drvPath, h);
+ return h;
}
/* See the header for interface details. These are the implementation details.
diff --git a/src/libstore/derivations.hh b/src/libstore/derivations.hh
index f9ba935e6..b966d6d90 100644
--- a/src/libstore/derivations.hh
+++ b/src/libstore/derivations.hh
@@ -210,7 +210,8 @@ DrvHashModulo hashDerivationModulo(Store & store, const Derivation & drv, bool m
/* Memoisation of hashDerivationModulo(). */
typedef std::map<StorePath, DrvHashModulo> DrvHashes;
-extern DrvHashes drvHashes; // FIXME: global, not thread-safe
+// FIXME: global, though at least thread-safe.
+extern Sync<DrvHashes> drvHashes;
/* Memoisation of `readDerivation(..).resove()`. */
typedef std::map<